1

次の POCO があります (Code First と EF 6.0.0 alpha 3 を使用):

public class RevBase
{
    [Key]
    public int Id{ get; set; }
}

public class ItemBase
{
    [Key]
    public int Id { get; set; }

    public List<RevBase> Revs { get; set; }
}

public class RevDev : RevBase
{
    public string Content { get; set; }
}

public class ItemDev : ItemBase
{
    public string Title { get; set; }
}

および次のコンテキスト

public class MyContext : DbContext
{
    DbSet<ItemDev> Items { get; set; }
}

今、クエリを実行したいのですcontext.Items.Include(i => i.Revs)が、どういうわけか EF に Revs をRevDevnotとしてロードするように伝えますRevBase

それは可能ですか、またはそれらをロードしてRevBase別のクエリを作成して、対応するRevDevインスタンスを取得する必要がありますか?

私が試したもう1つの方法は、からRevDevへの2番目のリレーションを作成することでしItemDevたが、EFはDBに2番目の外部キー列も作成しますが、これは実際には必要ありません...

4

2 に答える 2

1

Rev を RevBase ではなく RevDev としてロードする

指定されたRevBaseが でない場合、としてRevDevロードすることはできません。(すべての動物が犬というわけではありません。すべての動物を犬にすることはできません。一部の動物は猫です。) RevDev

実際、必要なのはタイプ別のフィルターIncludeだと思いますが、これはフィルター処理をまったくサポートしていないため、使用時に一般的に問題になります。次の 2 つのオプションがあります。

  • 明示的な読み込み (フィルタリングをサポート) を使用します。

    var items = context.Items.ToList();
    foreach (var item in items)
        context.Entry(item).Collection(i => i.Revs).Query()
            .Where(r => r is RevDev)
            .Load();
    

    これらは 1 + N 個の個別のデータベース クエリです。

  • プロジェクションを使用する:

    var items = context.Items
        .Select(i => new
        {
            Item = i,
            RevDevs = i.Revs.Where(r => r is RevDev)
        })
        .AsEnumerable()
        .Select(a => a.Item)
        .ToList();
    

    これは 1 つのデータベース クエリにすぎません。リレーションシップの自動修正Item.Revsにより、読み込まれた がコレクションに取り込まれRevDevsます。

于 2013-03-10T13:18:26.690 に答える
0

EntityFrameworkがデフォルトでそれを行うことがわかりました。コードに別のエラーがあり、なぜ機能しなかったのですか...

于 2013-03-10T13:12:36.053 に答える