简体   繁体   English

Dapper中间映射

[英]Dapper intermediate mapping

Slightly more advanced mapping then in my previous question :) 在我之前的问题中略微更高级的映射:)

Tables: 表:

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

Classes: 类别:

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

Is it possible to use one select to fill them all? 是否可以使用一个选择来填充它们? Something like this: 像这样的东西:

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

And then: 然后:

IEnumerable<Primary> primaries = connection.Query<Primary, Customer, Secondary, Tertiary, Primary>(
    sqlStatement,
    ... here comes dragons ...
    );

Edit1 - I could do it with two nested loops (foreach secondaries -> foreach tertiaries) and perform a query for each item, but just wonder if it could be done with single database call. Edit1 - 我可以使用两个嵌套循环(foreach secondaries - > foreach tertiaries)来执行它,并对每个项执行查询,但只是想知道是否可以使用单个数据库调用来完成。

Edit2 - maybe the QueryMultiple method would be appropriate here, but if I understand correctly then I would need multiple select statements. Edit2 - 也许QueryMultiple方法在这里是合适的,但如果我理解正确,那么我需要多个select语句。 In my real life example the select has more then 20 conditions (in where clause), where the search parameter could be null so I would not like to repeat all those where statements in all the queries... 在我的实际例子中,select有超过20个条件(在where子句中),其中search参数可以为null,所以我不想重复所有查询中所有语句的所有条件...

Dapper supports Multi Mapping, for documentation see: http://code.google.com/p/dapper-dot-net/ Dapper支持多映射,有关文档,请参阅: http//code.google.com/p/dapper-dot-net/

Here is one of the examples from one of the projects I'm currently working on: 以下是我目前正在开展的一个项目中的一个示例:

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

The trick is to use the splitOn option, to divide record-set into multiple objects. 诀窍是使用splitOn选项,将记录集划分为多个对象。

You can also check my question to see class structure for the above example: Dapper Multi-mapping Issue 您还可以检查我的问题以查看上述示例的类结构: Dapper Multi-mapping Issue

Seems like in all ORMs you will have several queries. 似乎在所有ORM中您将有几个查询。 You only can create your own solution, maybe based on Dapper or Petapoco. 您只能创建自己的解决方案,可能基于Dapper或Petapoco。 For example, combine all queries in one SQL batch: 例如,在一个SQL批处理中组合所有查询:

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

Then you can navigate from one recordset to nex by using DataReader.NextResult() 然后,您可以使用DataReader.NextResult()从一个记录集导航到nex

Then, need to combine data in memory to complete objects structure. 然后,需要结合内存中的数据来完成对象结构。

What about creating a SQLCommand, and then a bunch of SQLParameter objects. 那么创建一个SQLCommand,然后是一堆SQLParameter对象呢。 Ideally with a stored proc but doesn't have to be. 理想情况下,存储过程但不一定是。

Each of those output parameters could then be mapped back to your classes. 然后,每个输出参数都可以映射回您的类。

This other post on Stack has some code that could be relevant. Stack上的这篇文章有一些可能相关的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM