实体框架可以使用单个SaveChanges()添加许多相关实体吗?

时间:2014-09-23 19:07:34

标签: c# entity-framework identity

我正在向数据库编写许多(20多个)父子数据集,并且EF要求我在每个集合之间保存更改,否则它会抱怨无法找出主键。是否可以将数据刷新到SQL Server,以便EF可以从身份中获取主键,并在写入所有更改结束时发送SaveChanges?

foreach (var itemCount in itemCounts)
{
    var addItemTracking = new ItemTracking
    {
        availabilityStatusID = availabilityStatusId,
        itemBatchId = itemCount.ItemBatchId,
        locationID = locationId,
        serialNumber = serialNumber,
        trackingQuantityOnHand = itemCount.CycleQuantity
    };
    _context.ItemTrackings.Add(addItemTracking);
    _context.SaveChanges();
    var addInventoryTransaction = new InventoryTransaction
    {
        activityHistoryID = newInventoryTransaction.activityHistoryID,
        itemTrackingID = addItemTracking.ItemTrackingID,
        personID = newInventoryTransaction.personID,
        usageTransactionTypeId = newInventoryTransaction.usageTransactionTypeId,
        transactionDate = newInventoryTransaction.transactionDate,
        usageQuantity = usageMultiplier * itemCount.CycleQuantity
    };
    _context.InventoryTransactions.Add(addInventoryTransaction);
    _context.SaveChanges();
}

我想在大循环结束时只做一次我的SaveChanges。

3 个答案:

答案 0 :(得分:14)

如果您使用对象引用新创建的对象而不是ID,则不需要每次都保存更改:

var addItemTracking = new ItemTracking
{
    ...
}
_context.ItemTrackings.Add(addItemTracking);
var addInventoryTransaction = new InventoryTransaction
{
    itemTracking = addItemTracking,
    ...
};
_context.InventoryTransactions.Add(addInventoryTransaction);
...
_context.SaveChanges();

答案 1 :(得分:3)

因为它们都是新项而不是

itemTrackingID = addItemTracking.ItemTrackingID,

你可以选择

addItemTracking.InventoryTransaction = addInventoryTransaction;

(或任何相关的导航属性)并将_context.SaveChanges()完全拉出循环。当一切都是新的时,Entity Framework非常擅长插入对象图。保存包含新项目和现有项目的对象图表时,设置关联的ID始终更安全。

答案 2 :(得分:0)

怎么样:

var trackingItems = itemCounts
    .Select(i => new ItemTracking
        {
            availabilityStatusID = availabilityStatusId,
            itemBatchId = i.ItemBatchId,
            locationID = locationId,
            serialNumber = serialNumber,
            trackingQuantityOnHand = i.CycleQuantity
        });
_context.ItemTrackings.AddRange(trackingItems);
_context.SaveChanges();

var inventoryTransactions = trackingItems
    .Select(t => new InventoryTransaction
        {
            activityHistoryID = newInventoryTransaction.activityHistoryID,
            itemTrackingID = t.ItemTrackingID,
            personID = newInventoryTransaction.personID,
            usageTransactionTypeId = newInventoryTransaction.usageTransactionTypeId,
            transactionDate = newInventoryTransaction.transactionDate,
            usageQuantity = usageMultiplier * t.trackingQuantityOnHand
        });
_context.InventoryTransactions.AddRange(inventoryTransactions);
_context.SaveChanges();

但是我已经有很长一段时间没用EF了,上面的代码是用记事本写的,所以我不能保证它