很抱歉,但我因桌子拆分而感到困惑!
我有Product和ProductDetail实体,映射到表Product。
当我加载Products集合时,也会加载ProductDetails。
有人可能会解释为什么我可以阻止ProductDetails加载直到我真的想要它们?谢谢!
using (var ctx = new Context(cs))
{
var pc = ctx.Products.Local.Count();
var pdc = ctx.ProductDetails.Local.Count();
Assert.IsTrue(pc == 0);
Assert.IsTrue(pdc == 0);
ctx.Products.Load();
pc = ctx.Products.Local.Count();
pdc = ctx.ProductDetails.Local.Count();
Assert.IsTrue(pc >= 10); //OK so far
Assert.IsTrue(pdc == 0); //no, they are all there
}
我的上下文类和实体:
public class Context:DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
public Context():base()
{
}
public Context(string nameOrConnectionString) : base(nameOrConnectionString)
{
}
public DbSet<Product> Products { get; set; }
public DbSet<ProductDetail> ProductDetails { get; set; }
}
[Table("Product")]
public class Product
{
[Key]
public virtual int ProductId { get; set; }
public virtual string Name { get; set; }
}
[Table("Product")]
public class ProductDetail:Product
{
//[Key]
//public virtual int ProductId { get; set; }
//public virtual string Name { get; set; }
public virtual string Description { get; set; }
}
答案 0 :(得分:1)
发生这种情况的原因是因为ProductDetail
继承自Product
,从技术上讲,这是Table-per-Hierarchy mapping而不是简单的表格拆分。这意味着,无论何时加载所有Products
,您都必须加载所有ProductDetails
。 EF知道如何区分这两者,因此在加载每个实体时,框架会将其分类到您的上下文中的正确DbSet
- 它们都被添加到Products
集中,但也有一些也被添加到ProductDetails
设置。
幸运的是,解决方案非常简单:只需将ProductDetail
设为一个单独的类,而不是从Product
派生。然后你会得到你正在寻找的表:
[Table("Product")]
public class Product
{
[Key]
public int ProductId { get; set; }
public string Name { get; set; }
public virtual ProductDetail Details { get; set; }
}
[Table("Product")]
public class ProductDetail
{
[Key]
public int ProductId { get; set; }
public string Description { get; set; }
}
您还需要使用Fluent API在您的上下文中设置关系:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Product>()
.HasRequired(p => p.Details)
.WithRequiredPrincipal();
}
然后您只需加载Product
并使用myProduct.Details.Description
访问说明(您可能不需要手动访问ctx.ProductDetails
,如果有的话,使用此设置)
请注意,您必须启用延迟加载,或者在ctx.Products.Include(p => p.Details)
所需的所有查询中明确包含详细信息,以使其正常工作。
希望这有帮助!不同类型的表映射之间的区别有时可能非常微妙。