Mappatura intermedia di Dapper

c# dapper orm sql-server

Domanda

Mappatura leggermente più avanzata della mia precedente domanda :)

tabelle:

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

Classi:

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

È possibile utilizzare una selezione per riempirli tutti? Qualcosa come questo:

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

E poi:

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

Edit1 - Potrei farlo con due cicli annidati (foreach secondaries -> foreach terziari) ed eseguire una query per ogni elemento, ma mi chiedo solo se si potrebbe fare con una singola chiamata al database.

Edit2 - forse il metodo QueryMultiple sarebbe appropriato qui, ma se ho capito bene avrei bisogno di più istruzioni select. Nel mio esempio di vita reale la selezione ha più di 20 condizioni (nella clausola where), dove il parametro di ricerca potrebbe essere nullo quindi non vorrei ripetere tutti quelli in cui le dichiarazioni in tutte le query ...

Risposta accettata

Dapper supporta Multi Mapping, per la documentazione vedi: http://code.google.com/p/dapper-dot-net/

Ecco uno degli esempi di uno dei progetti a cui sto lavorando attualmente:

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

Il trucco è usare l'opzione splitOn, per dividere il set di record in più oggetti.

Puoi anche controllare la mia domanda per vedere la struttura della classe per l'esempio precedente: Problema di mappatura multipla di Dapper


Risposta popolare

Che ne dici di creare un SQLCommand e quindi un gruppo di oggetti SQLParameter. Idealmente con un proc memorizzato ma non deve essere.

Ognuno di questi parametri di output potrebbe quindi essere ricondotto alle classi.

Questo altro post su Stack ha un codice che potrebbe essere rilevante.



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché