[英]LINQ GroupJoin to IGrouping
想象一下,我的EF DataContext中有兩個實體:
class Person
{
int Id { get; set; }
...
}
class Address
{
int PersonId { get; set; }
string EMail { get; set; }
...
}
沒有導航屬性(並且我不想介紹任何屬性),因此我使用GroupJoin
獲取具有其地址的一系列People。
所以我在做:
var result = context.Set<Person>()
.GroupJoin(context.Set<Address>(),
x => x.Id,
x => x.PersonId, (person, addresses) =>
new { Person = person, Addresses = addresses.DefaultIfEmpty() });
result
當前為IQueryable<'a>
類型,其中'a
是new { Person, IEnumerable<Address> }
。
現在,我不知道如何進行轉換,因此無法得到IEnumerable<IGrouping<Person, Address>>
。 據我了解,這基本上是相同的結構。
如果您只需要替換匿名類型以便能夠定義函數結果,則可以為此使用自己的通用類。
public class Grouping<TKey, TELement>
{
public TKey Key { get; set; }
public IEnumerable<TELement> Elements { get; set; }
}
var result = context.Set<Person>()
.GroupJoin(context.Set<Address>(), x => x.Id, x => x.PersonId,
(person, addresses) => new Grouping<Person, Address>
{
Key = person,
Elements = addresses.DefaultIfEmpty()
});
結果的類型為IQueryable<Grouping<Person, Address>>
,可用於進一步應用Where
, OrderBy
等。
重要提示:請勿嘗試在您的類型中實現IGrouping<TKey, TElement>
(或通常為IEnumerable<T>
)-EF不喜歡那樣,它將拋出運行時異常。 也不要使用構造函數或工廠助手(例如Tuple.Create
。 簡單的屬性獲取/設置,別無其他(例如在實體類中)。 當然,您可以隨心所欲地調用該類及其成員。
可能最好的方法是:
public class Grouping<TKey, TElement> : IGrouping<TKey, TElement>
{
private IEnumerable<TElement> collection;
public Grouping(TKey key, IEnumerable<TElement> collection)
{
Key = key;
this.collection = collection;
}
public TKey Key
{
get;
set;
}
public IEnumerator<TElement> GetEnumerator()
{
return collection.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
接着:
var result = context.Set<Person>()
.GroupJoin(context.Set<Address>(),
x => x.Id,
x => x.PersonId, (person, addresses) =>
new Grouping<Person, Address>(person, addresses.DefaultIfEmpty() });
//Return type can be defined as IEnumerable<IGrouping<Person, Address>>
^注意,這沒有在EntityFramework上嘗試過。 您可能需要保留匿名對象,調用ToList
,然后選擇新的Grouping
類型。
或者,您可以使用Join
代替GroupJoin
。 這將為您提供每個地址一行(即使是同一個人),然后您可以使用.GroupBy()
@schglurps建議
所以:
context.Set<Person>()
.Join(context.Set<Address>(),
x => x.Id,
x => x.PersonId, (person, addresses) =>
new { Person = person, Addresses = addresses.DefaultIfEmpty() })
.GroupBy(x => x.Person, x => x.Addresses);
但是 ,如果一個人沒有地址 ,它將不會出現在結果集中。 如果可以的話,此解決方案會更簡潔。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.