[英]IReadOnlyCollection part of a LINQ query
我的模型(由Entity Framework生成,請記住,我已為示例簡化了模型)如下所示:
public class Person
{
public string Name { get; set; }
protected virtual ICollection<PersonHouseMapping> PersonHouseMappings { get; set; }
public virtual IReadOnlyCollection<House> GetHouses(Func<House, bool> where = null)
{
var houses = PersonHouseMappings.Select(x => x.House);
if (where != null)
houses = houses.Where(where);
return houses.ToList().AsReadOnly();
}
public void AddHouse(House house, DateTime movingDate)
{
PersonHouseMappings.Add(new PersonHouseMapping
{
Person = this,
House = house,
MovingDate = movingDate
});
}
}
public class House
{
public int Number { get; set; }
protected virtual ICollection<PersonHouseMapping> PersonHouseMappings { get; set; }
}
internal class PersonHouseMapping
{
public virtual Person Person { get; set; }
public virtual House House { get; set; }
public DateTime MovingDate { get; set; }
}
在Person和House之間存在N:M關系,由PersonHouseMapping實體表示。 通常,EF用導航屬性表示它,但是由於PersonHouseMapping除了關系的每個實體部分的PK之外還有一個額外的字段,因此它無法做到。
為了從我的庫用戶中抽象出PersonHouseMapping,因為它不像具有Navigation屬性那樣干凈,我已經保護了ICollection並通過在Person類中可以看到的方法公開了查詢/添加功能。 我不希望用戶修改返回的集合,因為他們可能會認為向“ GetHouses”的結果中添加新的House會保存到數據庫中,事實並非如此。 為了強迫他們調用“ AddHouse”,我將返回類型設為IReadOnlyCollection。
問題是,當我要構造一個包含與房屋相關的條件的Person查詢時,LINQ無法將表達式轉換為有效的Linq to Entities。 假設我們要查詢所有擁有1號房屋的人:
dbContext.Persons.Where(p => p.GetHouses(h => h.Number == 1).Any()).ToList();
這行不通,並引發異常:
LINQ to Entities does not recognize the method 'System.Collections.Generic.IReadOnlyCollection`1[Namespace.House] GetHouses(System.Func`2[Namespace.House,System.Boolean])' method, and this method cannot be translated into a store expression.
有道理。 但是如何在保留執行這些查詢的能力的同時完成我想要的? 是否有無法實例化到列表的類似IEnumerable的東西?
編輯:我認為通過返回IEnumerable而不是IReadOnlyCollection,查詢將可以工作(盡管它不能解決我的問題),但是不能。 為什么無法創建表達式?
編輯2:返回IEnumerable也不起作用的原因是問題不在於類型,問題在於在LINQ表達式中間有一個方法調用。 它需要直接轉換為商店查詢,因此沒有方法調用:(
非常感謝
唯一的方法是公開映射集合:
public virtual ICollection<PersonHouseMapping> PersonHouseMappings { get; set; }
並重新編寫查詢:
dbContext.Persons.Where(p => p.PersonHouseMappings.Any(m => m.House.Number == 1)).ToList();
EF無法解析您的方法並從中構建表達式樹的一部分。
實際上,我在您的查詢中看不到任何優點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.