dapper を使用して 1 つのクエリですべてSpaceShips
を選択するにはどうすればよいですか?Sightings
次のオブジェクトがあります。
public class SpaceShip
{
public int Id { get; set; }
public string DriveType { get; set; }
public List<Sighting> Sightings { get; set; }
}
public class Sighting
{
public int Id { get; set; }
public double Lat { get; set; }
public double Lon { get; set; }
}
次のスキーマを使用します。
If Exists(Select * from sysobjects where name = 'Sightings')
Drop Table Sightings
If Exists(Select * from sysobjects where name = 'SpaceShips')
Drop Table SpaceShips
CREATE TABLE [dbo].[SpaceShips](
[Id] [int] IDENTITY(1,1) NOT NULL,
[DriveType] [varchar](max) NOT NULL,
CONSTRAINT [PK_SpaceShips] PRIMARY KEY CLUSTERED
([Id] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
GO
CREATE TABLE [dbo].[Sightings](
[Id] [int] IDENTITY(1,1) NOT NULL,
[SpaceShipId] [int] NOT NULL,
[Lat] [decimal](18, 0) NOT NULL,
[Lon] [decimal](18, 0) NOT NULL,
CONSTRAINT [PK_Sightings] PRIMARY KEY CLUSTERED
([Id] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Sightings] WITH CHECK ADD CONSTRAINT [FK_Sightings_SpaceShips] FOREIGN KEY([SpaceShipId]) REFERENCES [dbo].[SpaceShips] ([Id])
GO
ALTER TABLE [dbo].[Sightings] CHECK CONSTRAINT [FK_Sightings_SpaceShips]
GO
Insert into SpaceShips (DriveType) Values ('X18-9'),('PV-276M')
Insert into Sightings (SpaceShipId, Lat, Lon) Values (1, 10, 90), (1, 20, 80), (1, 30, 70), (1, 40, 60)
Insert into Sightings (SpaceShipId, Lat, Lon) Values (2, 104, 64), (2, 105, 63), (2, 106, 62), (2, 107, 61)
私はダッパーを使用して、次のようSpaceShip
に関連するリストを選択しようとしていますSightings
:
using (var con = MuzakiFactory.OpenPortal())
{
try
{
var sql = @"Select * From SpaceShips ship left join Sightings s on s.SpaceShipId = ship.id";
var result = con.Query<SpaceShip, List<Sighting>, SpaceShip>
(sql, (ship, sightings) => {
ship.Sightings = sightings;
return ship;
});
return result;
}
catch (Exception ex)
{
Captains.Log(ex);
throw;
}
}
しかし、結果はSpaceShips
空のリストですSightings
。
アップデート
マークの提案を使用QueryMultiple
して自分で配線する方が簡単に思えました。これを機能させるにpublic int SpaceShipId {get;set;}
は、Sighting
クラスに追加する必要がありました。私はこれで終わった:
var sql = @"Select * From SpaceShips; Select * from Sightings;";
using (var multi = con.QueryMultiple(sql))
{
var ships = multi.Read<SpaceShip>().ToList();
var sightings = multi.Read<Sighting>().ToList();
foreach(var ship in ships)
{
ship.Sightings = new List<Sighting>(sightings.Where(x => x.SpaceShipId == ship.Id));
}
return ships;
}
注: もちろん、各クエリの where 句に親 ID を含める必要があります。