C# 有没有办法将多个嵌套的create-foreach循环展平为批量创建/插入?

C# 有没有办法将多个嵌套的create-foreach循环展平为批量创建/插入?,c#,sql,entity-framework,linq-to-entities,C#,Sql,Entity Framework,Linq To Entities,我遇到的情况是,我正在尝试提高嵌套foreach循环中一组creates的性能。它用于创建工单。在生成工单之前,可以添加任意数量的属性、供应商和工单项目/成本。将为添加的每个属性/供应商生成工单,因此所有选定的供应商都将为每个属性创建工单。如果添加太多,可能会变得一团糟。不幸的是,这些都是客户希望系统运行的方式,所以我不能重新设计它(或者它已经设计好了) 代码简化为仅包含相关部分- DbContext dbContext = new DbContext(); foreach (Property

我遇到的情况是,我正在尝试提高嵌套foreach循环中一组creates的性能。它用于创建工单。在生成工单之前,可以添加任意数量的属性、供应商和工单项目/成本。将为添加的每个属性/供应商生成工单,因此所有选定的供应商都将为每个属性创建工单。如果添加太多,可能会变得一团糟。不幸的是,这些都是客户希望系统运行的方式,所以我不能重新设计它(或者它已经设计好了)

代码简化为仅包含相关部分-

DbContext dbContext = new DbContext();

foreach (Property property in properties)
{
    foreach (Vendor vendor in vendors)
    {
        WorkOrder wo = new WorkOrder();
        WorkOrder.PropertyID = property.PropertyID;
        WorkOrder.VendorID = vendor.VendorID;
        dbContext.AddObject(wo);
        dbContext.SaveChanges();

        foreach (WorkOrderItemViewModel itemView in workOrderItemViewModels)
        {
            WorkOrderItem item = new WorkOrderItem();
            item.WorkOrderID = wo.WorkOrderID;
            dbContext.AddObject(item);
            dbContext.SaveChanges();

            foreach (WorkOrderItemCostViewModel costView in workOrderItemCostViewModels)
            {
                WorkOrderItemCost cost = new WorkOrderItemCost();
                cost.WorkOrderItemID = item.WorkOrderItemID;
                dbContext.AddObject(cost);
                dbContext.SaveChanges();
            }
        }
    }
}
这是许多嵌套的创建。如果他们在工单中添加太多内容,可能需要很长时间。一件物品只有两个物体,它转化为:

2个属性x 2个供应商=4个工单

2个工单项目x 4个工单=8个工单项目

2个项目成本x 8个工作订单项目=16个项目成本

总计=28

问题是我需要当前对象的前一个对象的ID。所以在我创建下一个对象之前,需要先创建它们。我看过一些解决方案,比如SQLite或大容量插入。。。。但看起来它们都需要采用标准的sql字符串格式。我尝试过研究是否可以将linq to entities生成的sql查询输出为字符串,但我没有发现任何有用的东西


有没有什么好方法可以在客户端的规范中重写此内容,以获得急需的性能提升?

我找到了答案。我不认为这会起作用,因为我不认为主键在创建/保存更改后会被填充到模型中(但它们确实如此)-这里是(非常简单):

DbContext-DbContext=new-DbContext();
列表工作顺序=新列表();
List workOrderItems=新列表();
foreach(属性中的属性)
{
foreach(供应商中的供应商)
{
工单wo=新工单();
WorkOrder.PropertyID=property.PropertyID;
WorkOrder.VendorID=vendor.VendorID;
dbContext.AddObject(wo);
工单。添加(wo);
}
}
dbContext.SaveChanges();
foreach(工单中的工单工单)
{
foreach(workOrderItemViewModels中的WorkOrderItemViewModel项目视图)
{
WorkOrderItem=新的WorkOrderItem();
item.WorkOrderID=wo.WorkOrderID;
dbContext.AddObject(item);
添加(项目)的工作指令;
}
}
dbContext.SaveChanges();
foreach(workOrderItems中的WorkOrderItem项)
{
foreach(workOrderItemCostViewModels中的WorkOrderItemCostViewModel成本视图)
{
WorkOrderItemCost成本=新的WorkOrderItemCost();
cost.WorkOrderItemID=item.WorkOrderItemID;
AddObject(成本);
}
}
dbContext.SaveChanges();

使用
dbContext.SaveChanges()只有一次将优化性能

改用这个:

DbContext dbContext = new DbContext();
foreach (Property property in properties)
{
    foreach (Vendor vendor in vendors)
    {
         WorkOrder wo = new WorkOrder();
         WorkOrder.PropertyID = property.PropertyID;
         WorkOrder.VendorID = vendor.VendorID;
         dbContext.AddObject(wo);
         foreach (WorkOrderItemViewModel itemView in workOrderItemViewModels)
         {
             WorkOrderItem item = new WorkOrderItem();
             item.WorkOrderID = wo.WorkOrderID;
             dbContext.AddObject(item);
             foreach (WorkOrderItemCostViewModel costView in workOrderItemCostViewModels) 
             {
                 WorkOrderItemCost cost = new WorkOrderItemCost();
                 cost.WorkOrderItemID = item.WorkOrderItemID;
                 dbContext.AddObject(cost);
             }
         }
     }
}
dbContext.SaveChanges();

是的,请看必须只有一个
SaveChanges()
,它应该在for循环之外。我仍然不理解“SQLite或大容量插入…但看起来它们都需要采用标准的sql字符串格式”。我认为大容量插入不会有任何问题。您可以在每个循环之外使用它作为最后一个要执行的过程。这对我来说不起作用,但是,它看起来与一些自定义代码相关,而实际上与您提供的代码无关。
DbContext dbContext = new DbContext();
foreach (Property property in properties)
{
    foreach (Vendor vendor in vendors)
    {
         WorkOrder wo = new WorkOrder();
         WorkOrder.PropertyID = property.PropertyID;
         WorkOrder.VendorID = vendor.VendorID;
         dbContext.AddObject(wo);
         foreach (WorkOrderItemViewModel itemView in workOrderItemViewModels)
         {
             WorkOrderItem item = new WorkOrderItem();
             item.WorkOrderID = wo.WorkOrderID;
             dbContext.AddObject(item);
             foreach (WorkOrderItemCostViewModel costView in workOrderItemCostViewModels) 
             {
                 WorkOrderItemCost cost = new WorkOrderItemCost();
                 cost.WorkOrderItemID = item.WorkOrderItemID;
                 dbContext.AddObject(cost);
             }
         }
     }
}
dbContext.SaveChanges();