2009-08-07 70 views
0

比方說,我有PersonSummary類,它結合了來自2個數據庫表Person和Address(具有Person的外鍵)的屬性(列),因此PersonSummary具有First Name,State和Zip。LINQ中的動態選擇

PersonSummary的創建可以在一個SELECT子句與 (人,地址=>新PersonSummary {人,地址})

我的數據訪問層沒有PersonSummary的知識,所以我想在較高級別添加select子句,並且僅在較低級別構建from,where等,以根據不同標準從Person和Address中選擇行,例如有像GetFemales()或GetPeopleInAState()方法。

有關如何做到這一點的任何建議?我的數據訪問函數應該返回表達式,而更高級別的方法只需要在Select子句上使用它?

最受讚賞的簽名/返回類型。

回答

0

當你使用底層的擴展方法LINQ使用,你幾乎可以做任何你想要的。

所以ALS只要你的數據層返回IQueryable的信息,你可以說

var withSummary = db.GetFemales() 
        .Select(p => new PersonSummary(p, p.Address)); 

如果您使用LINQ to SQL或EF,所有數據都與單個查詢檢索。但是,如果你的LINQ提供程序不夠先進,你可以嘗試

var withSummary = db.GetFemales().AsEnumerable() 
        .Select(p => new PersonSummary(p, p.Address)); 

但是,這需要你以某種方式預加載(或延遲加載)的地址。

1

你可以只添加擴展的IQueryable:

public static IQuearyable<Person> Famales(IQueryable<Person> this entry) 
{ 
    return entry.Where(p => p.Gender == Gender.Female); 
} 

public static IQuearyable<Person> LivingInState(IQueryable<Person> this entry, State state) 
{ 
    return entry.Where(p => p.State == state); 
} 

public static IQuearyable<Person> PeopleWithAddress(IQueryable<Person> this entry) 
{ 
    return entry.Where(p => p.Address != null); 
} 

// Use like this 
var marriedFemales = GetPersonsQuery().Females().Where(f => f.IsMarried) 
var femaleVictorians = GetPersonsQuery().Females().LivingInState(State.Victoria) 
var femaleVictorians = GetPersonsQuery().PeopleWithAddress() 
    .Females().Where(x => x.IsMarried) 
    .Select(x => new { x.LastName, x.Address}) 
+0

謝謝,那是一個很好的開始。 現在我可以進一步拆分GetPersonQuery(),以便我可以從數據層和業務層中的選擇/投影中獲取和連接? 一種方法是在數據層中定義PersonAddress實體,該實體將具有Person和Address,但我想避免這種情況。 因此,對於例如寫一個PeopleWithAddresses()方法(我不知道它會返回什麼類型),並且有 var marriedFemales = PeopleWithAddresses()。Females()。Where(f => f.IsMarried).Select new {Person。 LastName,Address.State)} 或者只是。選擇Person.Age – 2009-08-07 03:19:46

+0

您可以輕鬆地做到這一點。我會用另一個樣本更新答案。 – 2009-08-09 23:22:56