2

私は次のクラスを持っています(非常に単純化されています):

public class Person
{
    public int ID { get; set; }
}
public class Content
{
    public int ID { get; set; }
}
public class Image : Content
{
    public bool Private { get; set; }
    public Person Author { get; set; }
}
public class Tag
{
    public int ID { get; set; }
    public Content Content { get; set; }
    public Person Person { get; set; }
}

が であり、 ではないTags場所をすべて取得したいと思います( のプロパティを熱心にロードしている間)。これを実行しようとしてもうまくいかない例:ContentImageImagePrivateImage

var tags = context.Tags
    .Include("Content.Author")
    .Include("Person")
    .Where(t => !((Image)t.Content).Private);

次のエラーが表示されます。

タイプ「コンテンツ」をタイプ「イメージ」にキャストできません。LINQ to Entities は、EDM プリミティブ型または列挙型のキャストのみをサポートします。

そして、Where節を削除すると:

指定されたインクルード パスが無効です。EntityType 'Content' は、'Author' という名前のナビゲーション プロパティを宣言していません。

このアプローチを実現するには、どのようなクエリやモデル スキーマを変更する必要がありますか?

4

2 に答える 2

6

Where次の方法で句にフィルタを記述できます。

.Where(t => t.Content is Image && !(t.Content as Image).Private)

しかし、より大きな問題はInclude部品です。プロパティはAuthor派生型に対してのみ存在しImageますが、基本型(プロパティを持たない)Includeを読み込もうとします。これは のナビゲーション プロパティの型であるためです。ここしか使えない。ContentAuthorContentTagInclude

クエリをプロジェクションとして書き直すことができます。

var tags = context.Tags
    .Where(t => t.Content is Image && !(t.Content as Image).Private)
    .Select(t => new
    {
        Tag = t,
        Image = t.Content as Image, // possibly this line is not needed
        Author = (t.Content as Image).Author,
        Person = t.Person
    })
    .AsEnumerable()
    .Select(x => x.Tag)
    .ToList();

変更追跡を無効にしない限り (AsNoTrackingたとえば)、EF はオブジェクト グラフを自動的にまとめて、ロードされたタグにContent,Content.AuthorおよびPersonプロパティが設定されるようにする必要があります (ナビゲーション プロパティを でロードしたIncludeのように)。

ところで:派生型のナビゲーション プロパティを含める機能は、ここで UserVoiceで要求されます。あなたの状況とまったく同じではありませんが、コメント欄にはあなたのシナリオでもリクエストがあります。

于 2013-03-18T19:21:21.147 に答える
-1

クラス定義を次のようなものに変更してみてください...

class Person
{
  public int ID { get; set; }
}

class Content
{
  public int ID { get; set; }
}

class Image : Content
{
  public bool IsPrivate { get; set; }   
  public virtual Person Author { get; set; }
}

class Tag
{
public int ID { get; set; }
public Content Content { get; set; }
public Person Person { get; set; }
}

プライベートは、パブリックまたはプライベートの宣言と競合するため、プロパティの適切な名前のようには見えません。

于 2013-03-17T09:21:59.700 に答える