2012-04-19 30 views
9

Biraz daha gelişmiş haritalama sonra benim previous question :)Zarif ara haritalama

Tablo:

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

Sınıflar:

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

hepsiyle doldurmak için seçme birini kullanmak mümkün mü? Böyle bir şey: o zaman

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

Ve:

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

Edit1 - ve her öğe için bir sorgu gerçekleştirmek, ama sadece merak - I (> foreach üçlü sistem foreach ikinciller) iç içe geçmiş iki döngüler ile bunu yapabileceğimi Tek bir veritabanı çağrısı ile yapılabilir.

Düzenleme2 - belki de buradaki QueryMultiple yöntemi uygun olabilir, ancak doğru bir şekilde anlarsam birden çok seçim deyimine ihtiyacım olur. Benim gerçek hayattaki örnekte, seçimin daha sonra 20 parametresi (burada, cümlede), arama parametresinin null olabileceği için, tüm sorgularda ifadelerin olduğu tümleri tekrarlamak istemiyorum ...

cevap

4

Zarif belgelerine bakın, Multi Mapping destekler seçeneği, kayıt kümesini birden çok nesneye bölmek için kullanılır.

Ayrıca, yukarıdaki örnek için sınıf yapısını görmek için soruma da bakabilirsiniz: Dapper Multi-mapping Issue

1

Tüm ORM'lerde birkaç sorgunuz olacak. Sadece kendi çözümünüzü yaratabilirsin, belki Dapper veya Petapoco'ya dayanabilirsin. Örneğin, bir SQL toplu tüm sorguları birleştirmek:

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

Sonra

Ardından, nesneler yapıyı tamamlamak için bellekte verileri birleştirmek gerekir() DataReader.NextResult kullanarak NEX bir kayıt kümesinden gezinebilirsiniz .

1

SQLCommand ve sonra SQLParameter nesnelerini bir demet oluşturma hakkında. İdeal olarak saklanan bir proc ile ama olmak zorunda değil.

Bu çıktı parametrelerinin her biri daha sonra sınıflarınıza yeniden eşlenebilir. Yığın, ilgili olabilecek bazı kodları vardır. Şu anda üzerinde çalışıyorum İşte http://code.google.com/p/dapper-dot-net/

projelerden birinden örneklerinden biridir:

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

hüner splitOn kullanmaktır