Dapper中级映射

9

比我之前的问题中稍微复杂一些的映射 :)

表:

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<Secondary> Secondaries { get; set; }
}

public class Secondary
{
    public int Id { get; set; }
    public DateTime Date { get; set; }
    public List<Tertiary> 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; }
}

是否可能使用一个select来填充所有选项?就像这样:

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<Primary> primaries = connection.Query<Primary, Customer, Secondary, Tertiary, Primary>(
    sqlStatement,
    ... here comes dragons ...
    );

编辑1 - 我可以使用两个嵌套循环(对于每个次要项目-> 对于每个三级项目)并为每个项目执行查询来完成操作,但我想知道是否可以通过单个数据库调用完成。

编辑2 - 可能在这里QueryMultiple方法比较合适,但如果我理解正确,那么我需要多个select语句。在我的实际示例中,选择具有20多个条件(在where子句中),其中搜索参数可能为空,因此我不希望在所有查询中重复所有这些where语句...

3个回答

4

Dapper支持多结果映射,详见文档:http://code.google.com/p/dapper-dot-net/

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

        var accounts2 = DbConnection.Query<Account, Branch, Application, Account>(
                    "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多映射问题

1

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

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

接下来,您可以使用DataReader.NextResult()从一个记录集导航到下一个。

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


1
创建一个SQLCommand,然后一堆SQLParameter对象怎么样?最好使用存储过程,但不是必须的。
然后可以将这些输出参数映射回你的类。 Stack上的这篇文章有一些相关的代码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接