我有两个数据库表,一个用于保存已完成的项,另一个用于保存不完整的项。两个表的结构相同。在某些情况下,我只想查询其中一个表,但在其他情况下,我想查询两个表的串联。
类
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
{
}
映射(Fluent 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;
当试图将两者结合起来时,我无法弄清楚语法。下面的答案中的一个解决方案涉及使用.AsEnumerable
进行投射,但这不是我正在寻找的,因为它立即进行评估。
db.As.AsEnumerable().Concat<SomeBase>(db.Bs);
db.As.Cast<SomeBase>().Concat(db.Bs.Cast<SomeBase>());
如何连接数据库站点上相同的两个派生类?
编辑: 在最低级别,我收到这些错误
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.
答案 0 :(得分:2)
只需定义一个
DbSet<SomeBase> Bases { get; set;}
属性,用于访问基类的所有实例。框架应该以正确的方式(联合)组合查询,以包括来自两个表的实例。
(您使用TPC继承策略)
答案 1 :(得分: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 }));
答案 2 :(得分:1)
怎么样:
var concatenatedSet = db.As.Local.OfType<SomeBase>().Concat(db.Bs.Local.OfType<SomeBase());