Dapper Zwischenmapping

c# dapper orm sql-server

Frage

Etwas fortgeschrittenere Mapping dann in meiner vorherigen Frage :)

Tabellen:

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

Klassen:

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

Ist es möglich, eine Auswahl zu verwenden, um alle zu füllen? Etwas wie das:

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

Und dann:

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

Edit1 - Ich könnte es mit zwei verschachtelten Schleifen (Foreach Secondaries -> foreach tertiaries) tun und führen Sie eine Abfrage für jedes Element, aber nur darüber nach, ob es mit einzelnen Datenbankaufruf getan werden könnte.

Edit2 - vielleicht wäre die QueryMultiple-Methode hier angebracht, aber wenn ich das richtig verstehe, würde ich mehrere select-Anweisungen benötigen. In meinem realen Beispiel hat das select mehr als 20 Bedingungen (in where-Klausel), wobei der Suchparameter null sein könnte. Daher möchte ich nicht alle where-Anweisungen in allen Abfragen wiederholen ...

Akzeptierte Antwort

Dapper unterstützt Multi Mapping, Dokumentation siehe: http://code.google.com/p/dapper-dot-net/

Hier ist eines der Beispiele aus einem der Projekte, an denen ich gerade arbeite:

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

Der Trick besteht darin, die Option splitOn zu verwenden, um Datensätze in mehrere Objekte aufzuteilen.

Sie können auch meine Frage überprüfen, um Klassenstruktur für das obige Beispiel zu sehen: Dapper Multi-Mapping-Problem


Beliebte Antwort

Was ist mit dem Erstellen eines SQLCommand und dann einer Reihe von SQLParameter-Objekten? Idealerweise mit einem gespeicherten Proc, muss aber nicht sein.

Jeder dieser Ausgabeparameter könnte dann wieder auf Ihre Klassen abgebildet werden.

Dieser andere Beitrag auf Stack enthält Code, der relevant sein könnte.



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum