web-dev-qa-db-ja.com

Entity Framework Core 3.1が「Includeはエンティティ以外のクエリ可能で使用されました」例外をスローします

ASP.NET Core 3.1ベースのプロジェクトで、Entity Framework Core 3.1をORMとして使用しています。

次の2つのエンティティモデルがあります

public class PropertyToList
{
    public int Id { get; set; }
    public int ListId { get; set; } 
    public int UserId { get; set; }
    public int PropertyId { get; set; }
    // ... Other properties removed for the sake of simplicity

    public virtual Property Property { get; set; }
}

public class Property
{
    public int Id { get; set; }
    // ... Other properties removed for the sake of simplicity
    public int TypeId { get; set; } 
    public int StatusId { get; set; }
    public int CityId { get; set; }

    public virtual Type Type { get; set; }
    public virtual Status Status { get; set; }
    public virtual City City { get; set; }
}

ユーザーが関係しているすべてのプロパティをクエリしようとしています。 PropertyToListオブジェクトは、ユーザーがプロパティに関連しているかどうかを教えてくれます。これが私がやったことです

// I start the query at a relation object
IQueryable<Property> query = DataContext.PropertyToLists.Where(x => x.Selected == true)
                                        .Where(x => x.UserId == userId && x.ListId == listId)
                                        // After identifying the relations that I need,
                                        // I only need to property object "which is a virtual property in" the relation object
                                        .Select(x => x.Property)
                                        // Here I am including relations from the Property virtual property which are virtual properties
                                        // on the Property
                                        .Include(x => x.City)
                                        .Include(x => x.Type)
                                        .Include(x => x.Status);

List<Property> properties = await query.ToListAsync();

しかし、そのコードはこのエラーをスローしています

インクルードはクエリ不可能なエンティティで使用されています

この問題の原因は何ですか?どうすれば修正できますか?

2
user12310517

親エンティティを参照した直後にインクルードを置きます。 ThenIncludeを実行すると、含まれているエンティティの子エンティティも取得できます。 ThenIncludeごとに1つのインクルードを実行する必要があります。

次に、/フィルタリングを含めた後に選択を行うことができます。何かのようなもの:

var query = DataContext.PropertyToLists
.Include(p => p.Property).ThenInclude(p => p.City)
.Include(p => p.Property).ThenInclude(p => p.Type)
.Include(p => p.Property).ThenInclude(p => p.Status)
.Where(p => p.Selected == true && p.UserId == userId && p.ListId == listId)
.Select(p => p.Property);
1
JMP

観察結果、ドメインモデルPropertyToListとPropertyの両方に仮想プロパティがあります。その上で、Include演算子を使用してこれらのプロパティを選択しています。

これは必要ありません。プロパティがvirtualで定義されている場合、遅延読み込みされます。したがって、インクルードは必要ありません。遅延読み込みは推奨されない方法です。includeを使用する方が良いため、必要なグラフプロパティのみを選択します。

0
Joe Ipe