c# - 实体框架:使用本地对象设置导航属性(尚未保存到数据库中)
问题描述
我正在使用 Entity Framework 版本 6,需要在很短的时间内将数千个对象批量插入数据库。
因此我更改DbContext.Configuration.AutoDetectChangesEnabled
为 false 并且仅SaveChanges
在添加了许多项目后使用。
我们称它为实体,它Person
自身有一个导航属性,例如Supervisor
。
现在我想将一个人添加到数据库中,并希望使用刚刚添加到上下文中的主管填充导航属性(只是本地,而不是在数据库中)之前的迭代。
由于性能原因,我只是在 200 万人之后调用 SaveChanges()。如果我在SaveChanges
该列Supervisor
始终为 NULL 之后查看数据库。如何添加导航属性?
奇怪的是,我的实体模型有四个导航属性,分别命名为 Supervisor1
、和 。为什么实体模型会为一个数据库约束创建四个导航属性?Supervisor2
Supervisor11
Supervisor3
详细解释我的问题:这是我的 数据库结构。EntityFramework 创建这个模型。
有一个循环来处理来自 csv 文件的数据:
db.DbContext.Configuration.AutoDetectChangesEnabled = false; // for performance
///...
while (!parser.EndOfData)
{
// process data from a csv file with a name and a supervisorId
db.AddNewPerson(name, supervisorId);
}
db.SaveChanges();
db.DbContext.Configuration.AutoDetectChangesEnabled = true;
这是数据访问层的方法:
public void AddNewPerson(string name, long? supervisorId)
{
var dbSetPerson = dbContext.Set<Person>();
var newPerson = new Person(name);
dbSetPerson.Add(newPerson);
if (supervisorId != null)
{
var supervisor = dbSetPerson.Local.FirstOrDefault(x => x.PersonId == supervisorId); // first look if the supervisor was just processed in this loop
if (supervisor == null)
supervisor = dbSetPerson.FirstOrDefault(x => x.PersonId == supervisorId); // if the was no person found look in the database
if (supervisor != null)
newPerson.Person2 = supervisor;
}
}
提前谢谢你的帮助!
解决方案
我认为你的问题是,实体在这个阶段没有存储到数据库中,并且 EF(代理)不知道它。您可以做的是在调用 StoreChanges() 之后附加它:
yourContext.Persons.Attach(justAddedPerson);
但是当你添加一些代码时,我可以给出更具体的答案。
更新 根据您的编辑(我猜 Id 是 int 而不是自动创建的)我会建议以下内容:
var persons = new List<Person>();
while (!parser.EndOfData)
{
var person = new Person { Name = parser... }
person.SupervisorId = parser...
list.Add(person);
}
dbSet.AddRange(persons);
dbContext.SaveChanges();
首先进行解析,然后进行数据库操作。EF 足够聪明,可以在您不更改配置时设置导航属性,这不再是必需的,因为 AddRange() 应该比 Add() 快得多,因为它只调用一次 detectchanges。通过仅设置主管 ID,
推荐阅读
- c# - 适用于 Android 的 Agora unity 2018 构建问题
- node.js - 如何向 mongodb 集合添加新字段并使其独一无二?
- android - Android 模拟器给出错误“重置冷启动:仿真引擎失败”并退出
- android - recyclerview viewholder布局中的更改约束 - android
- c++ - 当头文件(a.hpp)包含在头文件(b.hpp)对应的源文件(b.cpp)和main.cpp中时,C ++修复多重定义错误
- django - Django 无效的 HTTP_HOST 标头 Elastic Beanstalk
- java - 在数据库中保存玩家手
- javascript - 显示选定的单词 [Javascript]
- python - 类变量 - 缺少一个必需的位置参数
- c - 如果范围是不同的结构定义,结构声明是否存在于声明它的范围之后?