c# - EF 6 添加后获取实体
问题描述
我在我的 .NET MVC 应用程序中使用 EF 6。我有这些课程:
public class Member
{
public int ID { get; set; }
public string Name { get; set; }
public int FactoryID { get; set; }
public Factory Factory { get; set; }
}
public class Factory
{
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Member> Members { get; set; }
}
要添加的代码:
var newMember = new Member();
newMember.Name = 1;
newMember.FactoryID = 2;
context.Members.Add(newMember);
context.SaveChanges();
获取代码:
var member = context.Members.SingleOrDefault(x => x.ID == id);
var factory = member.Factory;
因此,当我添加Member
一个 API 调用时,然后定义Member
另一个 API 调用。Member.Factory
当我尝试Member
添加后立即获取时,Member.Factory
就是NULL
.
它的原因是什么?以及如何解决?
解决方案
它有时会起作用但在其他情况下不起作用的原因是,当您通过 ID 引用实体时,EF 会提供它知道的相关实体。如果启用了延迟加载,EF 将去数据库拉回它不知道的任何相关实体。但是,在序列化响应时,延迟加载可能会导致性能问题或循环引用错误。
例如,关闭延迟加载:
如果我这样做:
using (var context = new MyContext())
{
var member = new Member
{
FactoryId = 3;
// ...
}
context.Members.Add(member);
context.SaveChanges();
return member;
}
返回的成员的“工厂”引用将为#null,因为该 EF 上下文不知道工厂 ID 3 实际是什么。如果存在 Factory ID #3 的数据记录,但上下文不知道,则插入将成功。
如果在另一个例子中我做这样的事情:
using (var context = new MyContext())
{
// Call some code using this context that results in the following running...
var factory = context.Factories.Single(x => x.FactoryId == 3);
// more code...
var member = new Member
{
FactoryId = 3;
// ...
}
context.Members.Add(member);
context.SaveChanges();
return member;
}
在这种情况下,EF 将连同成员一起返回 Factory #3,因为上下文实例知道 Factory #3。保存成员时,会自动关联已知引用。
上面的示例在 using 块中使用了 DbContext,这使得场景看起来很明显,但是,对于使用 IoC 容器将 DbContext 范围限定为请求的代码,例如对于跨各种给定场景的任何给定场景,它可能不太清晰可能会调用方法等来确定 DbContext 可能知道或不知道的实体。
在处理要返回有关实体及其引用的详细信息的引用时,或者以下代码将从访问引用中受益时,我的典型建议是在实体中设置引用,而不是 FK。通过这种方式,您可以确保您正在创建的实体处于完整且适合用途的状态。
例如:
using (var context = new MyContext())
{
var factory = context.Factories.Single(x => x.FactoryId == factoryId);
var member = new Member
{
Factory = factory;
// ...
}
context.Members.Add(member);
context.SaveChanges();
return member;
}
我避免在我的实体中完全公开 FK 以强制使用引用,并使用影子属性 (EFCore) 和映射 (EF6) 来确保我的实体中无法访问 FK。FK 的问题在于,在编辑同时具有引用和 FK 列的实体时,有 2 个事实来源。更新工厂会更改工厂引用,还是更新 FactoryId?如果我有一个指向 Factory ID 3 的 Factory 引用,但我将 Member 上的 FactoryId 更改为 4,该怎么办?一些代码可能取决于 FK,而其他代码可能会转到工厂参考。
显式使用引用意味着相关实体在该点被断言(而不是在 SaveChanges 上等待任意数量的 FK 违规)。它将使用上下文已加载的任何已加载引用,或在需要时转到数据库。
我在引用上使用 FK 的地方是用于批量操作,我只想尽快更新或插入大量信息。在这些情况下,我使用带有 FK 的简单实体定义的有界上下文,并且没有引用来创建、设置 FK 和保存。无需返回完整的数据和引用。
推荐阅读
- entity-framework - 使用实体框架查询格式化日期时间未使用 ToString("MM/dd/yyyy") 正确排序
- python - 连接 numpy 数组和 keras 层
- javascript - 推送数组中的值以匹配特定格式
- python - 将数据框列表附加到python中的数据框列表
- excel - 将所有列值与 Excel 中的单个单元格进行比较
- r - R中的简单绘图
- python - Python pytz:显示时区的实际时间
- ios - 检测对 UITableViewCell 内的 UIViewCollectionCell 的点击
- api - 如何在具有不同查询参数的多个匹配 URL 上获取特定存根
- java - C#中3DES加密的java等价物是什么