我正在使用Entityframework 6,我试图在数据库中插入父子类数据。 我正在使用Entityframework.BulkInsert来插入数据。我在所有表中都有 autoIncrement int primary key
我的目标如下:
var parentObjects= new List<parentObject>();
var childObjects= new List<childObject>();
for (int i = 0; i <= 100; i++)
{
var parentObj= new parentObject()
{
Name="p1",
Address="a1"
};
childObjects= SeedInitializer.ChildItems.OrderBy(x => new Random().Next()).Take(2).ToList();//this gets 2 child objects
foreach (var childObj in childObjects)
{
childObj .ParentObject= parentObj;
//childObj .CommissionPlanId = i; //tried this still not working
parentObj.ChildObjects.Add(childObj );
}
parentObjects.Add(parentObj);
}
//when I do a quickwatch on parentObjects, i see child objects in each parentObject, but
//with the last id of parentObject
context.BulkInsert(parentObjects, 1000);
context.SaveChanges();
在保存时,在childObject中创建的只有2条记录是使用错误的parentObject id创建的,即0 在创建父对象时,我无法理解为什么没有创建子项。有人能帮我理解我在做错的地方吗?
答案 0 :(得分:1)
我认为没有一种简单的方法可以完成此任务,因为为了插入子项,您必须实际插入父项并获取其ID。普通EF插入的优势在于每个INSERT
还会嵌入SELECT
来获取刚刚生成的标识符,以便它可以用来为子项推送它(如果有的话)。
一种可能的解决方案如下:
Guid RefProperty
添加到ParentObject
类型,该类型也会保留Guid BatchId
添加到ParentObject
类型,该类型也会保留Guid RefProperty
添加到未保留的ChildObject
类型使用以下(主要是伪代码)序列保存整个结构
var batchId = new Guid();
parentObjects.ForEach(item => item.BatchId = batchId);
// set RefProperty for all parents and children to reflect proper parentation
TransactionScope scope = null;
try
{
context.BulkInsert(parentObjects, 1000);
var newParents = context.ParentObjects.Where(_ => _.BatchId = batchId);
var refPropMap = newParents.ToDictionary(_ => _.RefProperty, _ => ParentId);
var childObjects.ForEach(item => item.ParentId = refPropMap[item.RefProperty]);
context.BulkInsert(childObjects, 1000);
DataAccess.SaveChanges();
scope.Complete();
}
catch (Exception exc)
{
scope?.Dispose();
}
注意:未经过测试
这非常难看,但它应该可以解决这个问题:尽量减少到SQL Server的往返行程,但仍然是一个单一的事务。
为了使SELECT
更快,ParentObject表上的索引应放在BatchId
上,包括(覆盖)其密钥。
替代方案:将这些表的设计更改为不使用自动增量,而是使用UNIQUEIDENTIFIER
列。这样,可以在进行插入之前设置所有标识符。
答案 1 :(得分:1)
免责声明:我是EntityFramework.BulkInsert
的所有者你不能。
此功能从未实施过。
免责声明:我是Entity Framework Extensions
的所有者但是,这个新库(不是免费的)可以轻松处理这种情况。
BulkSaveChanges的工作方式与SaveChanges(处理父/子)完全相同,但速度更快!
支持所有方法:
实施例
// Easy to use
context.BulkSaveChanges();
// Easy to customize
context.BulkSaveChanges(bulk => bulk.BatchSize = 100);