Dapper中间映射

在我之前的问题中略微更高级的映射:)

表:

create table [Primary] ( Id int not null, CustomerId int not null, CustomerName varchar(60) not null, Date datetime default getdate(), constraint PK_Primary primary key (Id) ) create table Secondary( PrimaryId int not null, Id int not null, Date datetime default getdate(), constraint PK_Secondary primary key (PrimaryId, Id), constraint FK_Secondary_Primary foreign key (PrimaryId) references [Primary] (Id) ) create table Tertiary( PrimaryId int not null, SecondaryId int not null, Id int not null, Date datetime default getdate(), constraint PK_Tertiary primary key (PrimaryId, SecondaryId, Id), constraint FK_Tertiary_Secondary foreign key (PrimaryId, SecondaryId) references Secondary (PrimaryId, Id) ) 

类别:

 public class Primary { public int Id { get; set; } public Customer Customer { get; set; } public DateTime Date { get; set; } public List Secondaries { get; set; } } public class Secondary { public int Id { get; set; } public DateTime Date { get; set; } public List Tertiarys { get; set; } } public class Tertiary { public int Id { get; set; } public DateTime Date { get; set; } } public class Customer { public int Id { get; set; } public string Name { get; set; } } 

是否可以使用一个选择来填充它们? 像这样的东西:

 const string sqlStatement = @" select p.Id, p.CustomerId, p.CustomerName, p.Date, s.Id, s.Date, t.Id, t.Date from [Primary] p left join Secondary s on (p.Id = s.PrimaryId) left join Tertiary t on (s.PrimaryId = t.PrimaryId and s.Id = t.SecondaryId) order by p.Id, s.Id, t.Id "; 

然后:

 IEnumerable primaries = connection.Query( sqlStatement, ... here comes dragons ... ); 

Edit1 – 我可以用两个嵌套循环(foreach secondaries – > foreach tertiaries)来执行它,并对每个项执行查询,但只是想知道是否可以使用单个数据库调用来完成。

Edit2 – 也许QueryMultiple方法在这里是合适的,但如果我理解正确,那么我需要多个select语句。 在我的现实生活中,select有超过20个条件(在where子句中),其中search参数可以为null,所以我不想重复所有查询中所有语句的所有条件…

Dapper支持Multi Mapping,有关文档,请参阅: http : //code.google.com/p/dapper-dot-net/

以下是我目前正在开展的一个项目中的一个示例:

  var accounts2 = DbConnection.Query( "select Accounts.*, SplitAccount = '', Branches.*, SplitBranch = '', Applications.*" + " from Accounts" + " join Branches" + " on Accounts.BranchId = Branches.BranchId" + " join Applications" + " on Accounts.ApplicationId = Applications.ApplicationId" + " where Accounts.AccountId <> 0", (account, branch, application) => { account.Branch = branch; account.Application = application; return account; }, splitOn: "SplitAccount, SplitBranch" ).AsQueryable(); 

诀窍是使用splitOn选项,将记录集划分为多个对象。

您还可以检查我的问题以查看上面示例的类结构: Dapper Multi-mapping Issue

似乎在所有ORM中您将有几个查询。 您只能创建自己的解决方案,可能基于Dapper或Petapoco。 例如,在一个SQL批处理中组合所有查询:

 select * from Primary where ... select * from Secondary where ... select * from Tertiary where ... 

然后,您可以使用DataReader.NextResult()从一个记录集导航到nex

然后,需要结合内存中的数据来完成对象结构。

那么创建一个SQLCommand,然后是一堆SQLParameter对象呢? 理想情况下,存储过程但不一定是。

然后,每个输出参数都可以映射回您的类。

Stack上的这篇文章有一些可能相关的代码。