我正在使用EF 6.X的Code First方法。 有两个实体和一个上下文:
class Product
{
long Id { get; set; }
string Name { get; set; }
ProductCategory ProductCategory { get; set; }
}
class ProductCategory
{
long Id { get; set; }
string Name { get; set; }
}
class ProductContext : DbContext
{
public DbSet<Product> Products { get; set; }
public DbSet<ProductCategory> ProductCategories { get; set; }
}
当我使用预期的命名约定时,我能够从模型创建数据库,添加项目并将其读回 - 无需数据注释,也无需使用流畅的API。 实际上,我确实使用了流畅的API在某些属性上设置HasMaxLength,但该配置代码没有设置密钥或外键。
重要的一点是,在调用以下内容时:
Product product = context.Products.Find(1).FirstOrDefault();
产品的ProductCategory使用ProductCategory实例正确填充。 我遇到的问题是这种行为似乎不一致。
在WebApi控制器中,我创建了一个ProductContext类的实例,并且读取执行与上面代码片段相同的操作。 结果是正确实例化的Product,但其ProductCategory属性设置为null。
任何人都可以解释这两种用法之间的差异吗?我的DbContext派生上下文能够将Product表中的外键条目转换为ProductCategory类的实例的先决条件是什么?
答案 0 :(得分:1)
默认情况下,实体框架在从DB加载对象时不会加载相关对象。你必须:
使用Include
声明:
context.Products.Include(p => p.ProductCategory).FirstOrDefault(p => p.Id == 1);
或者通过将导航属性标记为virtual
来使用延迟加载:
class Product
{
long Id { get; set; }
string Name { get; set; }
virtual ProductCategory ProductCategory { get; set; }
}
然后在您第一次触摸时加载ProductCategory
。
或手动加载参考:
context.Entry(product).Reference(p => p.ProductCategory).Load();