簡體   English   中英

LINQ查詢的IReadOnlyCollection部分

[英]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關系,由PersonH​​ouseMapping實體表示。 通常,EF用導航屬性表示它,但是由於PersonH​​ouseMapping除了關系的每個實體部分的PK之外還有一個額外的字段,因此它無法做到。

為了從我的庫用戶中抽象出PersonH​​ouseMapping,因為它不像具有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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM