【问题标题】:Dapper intermediate mappingDapper 中间映射
【发布时间】:2012-04-19 07:39:54
【问题描述】:

比我的previous question 更高级的映射:)

表格:

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; }
}

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

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 ...
    );

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

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

【问题讨论】:

    标签: c# sql-server orm dapper


    【解决方案1】:

    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 Multi-mapping Issue

    【讨论】:

      【解决方案2】:

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

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

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

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

      【讨论】:

        【解决方案3】:

        如何创建一个 SQLCommand,然后是一堆 SQLParameter 对象。理想情况下使用存储过程,但不必如此。

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

        Stack 上的This other post 有一些可能相关的代码。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-20
          • 1970-01-01
          • 2012-08-18
          • 2019-01-06
          • 1970-01-01
          相关资源
          最近更新 更多