4

2 つのデータベース テーブルがあり、1 つは完了したアイテムを保持し、もう1 つは未完了のアイテムを保持します。両方のテーブルの構造は同じです。これらのテーブルの 1 つだけを調べたい場合もあれば、両方のテーブルの連結をクエリしたい場合もあります。

クラス

public abstract class SomeBase
{
    public int Id {set;get;}
    public string Item1 {set;get;}
    public string Item2 {set;get;}
}
public class A : SomeBase
{
}
public class B : SomeBase
{
}

マッピング (流暢な API)

public class SomeDatabase : DbContext
{
    public DbSet<A> As {set;get;}
    public DbSet<B> Bs {set;get;}
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<A>().Map(m =>
        {
            m.MapInheritedProperties();
            m.ToTable("ATable", "SomeSchema");
        }
        modelBuilder.Entity<B>().Map(m =>
        {
            m.MapInheritedProperties();
            m.ToTable("BTable", "SomeSchema");
        }
    }
}

この設定を使用すると、両方のテーブルを個別にクエリできます

var db = new SomeDatabase();
var a = db.As;
var b = db.Bs;

2 つを結合しようとすると、構文がよくわかりません。以下の回答の1つの解決策は、それを使用してキャストすることを含みます.AsEnumerableが、それはすぐに評価されるため、私が探しているものではありません。

db.As.AsEnumerable().Concat<SomeBase>(db.Bs);
db.As.Cast<SomeBase>().Concat(db.Bs.Cast<SomeBase>());

データベース サイトで同一の 2 つの派生クラスを連結するにはどうすればよいですか?

編集:最低レベルで、これらのエラーが発生しています

db.As.Cast<SomeBase>();
Unable to cast the type 'Test.Models.A' to type 'Test.Models.SomeBase'. LINQ to Entities only supports casting Entity Data Model primitive types.

db.As.OfType<SomeBase>();
'Test.Models.SomeBase' is not a valid metadata type for type filtering operations. Type filtering is only valid on entity types and complex types.

関連する質問: 2 つの異なる IQueryable/List/Collection を同じ基本クラスと組み合わせる方法は? LINQ ユニオンと共分散の問題

4

3 に答える 3

2

Simply define a

DbSet<SomeBase> Bases { get; set;}

property to access all instances of the base class. The framework should combine the query the right way (union) to include the instances from both tables.

For more details check out e.g. this article: http://weblogs.asp.net/manavi/archive/2011/01/03/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-3-table-per-concrete-type-tpc-and-choosing-strategy-guidelines.aspx

(You use the TPC inheritance strategy)

于 2013-05-16T21:24:30.470 に答える
1

どうですか:

var concatenatedSet = db.As.Local.OfType<SomeBase>().Concat(db.Bs.Local.OfType<SomeBase());
于 2013-05-16T21:20:13.797 に答える
1

もっとエレガントな方法があるかもしれませんが、ユニオンはそれを行うべきだと思います:

db.As.Select(x => new { x.Id, x.Item1, x.Item2 } )
.Union(db.Bs.Select(x => new { x.Id, x.Item1, x.Item2 }));

As のいくつかのフィールドと Bs のいくつかのフィールドを含めたい場合は、次のようになります。

db.As.Select(x => new { x.Id, x.Item1, x.Item2, x.Afield, Bfield = null } )
.Union(db.Bs.Select(x => new { x.Id, x.Item1, x.Item2, AField = null, x.Bfield }));
于 2013-05-16T21:11:59.437 に答える