在foreach循环中使用dbcontext.savechanges

时间:2016-12-23 19:10:56

标签: entity-framework c#-4.0 model-view-controller

我有以下方法,即将数据写入数据库中的两个表。我需要写一个集合 到foreach部分的数据库。如果我在每次迭代中调用saveChanges都没关系 循环还是有更好的方法吗?

         public string SaveInformationToDb(Customerproductdto objDataCollected, List<Productopportunity> objcheckedData)
                {
                    int  generatedLeadDescriptionId = 0;
                    string result = "Failure";

                    using (var dbcontext = new LEADSEntities())
                    {
                        using (var dbContextTransaction = dbcontext.Database.BeginTransaction())
                        {
                            var leadDescription = new LEAD_DESCRIPTION
                            {
                                DETAIL = objDataCollected.LeadDetails,
                                EstimatedRevenue = Convert.ToDecimal(objDataCollected.EstimatedRevenue),
                                CustomerContact = objDataCollected.CustomerContact,
                                CustomerPhone = objDataCollected.CustomerPhone,
                                CustomerEmail = objDataCollected.CustomerEmail
                            };
                            dbcontext.LEAD_DESCRIPTION.Add(leadDescription);
                            dbcontext.SaveChanges();
                            generatedLeadDescriptionId = leadDescription.ID;

                            //process data in the collection
                            foreach (var VARIABLE in objcheckedData)
                            {
                                var leadMetric = new LEAD_METRIC
                                {
                                    EMPLID = objDataCollected.EmployeeNumber,
                                    CustomerNumber = objDataCollected.CustomerNumber,
                                    ProductTypeId = GetLeadProductOpportunityId(VARIABLE.ProductName),
                                    LeadId = generatedLeadDescriptionId
                                };
                                dbcontext.LEAD_METRIC.Add(leadMetric);
                                dbcontext.SaveChanges();
                            }
                            result = "Success";
                            dbContextTransaction.Commit();
                        }               
                    }
                    return result;

                }

3 个答案:

答案 0 :(得分:1)

我想你的public virtual ICollection<LEAD_METRIC> Metrics课程中有LEAD_DESCRIPTION等导航属性。如果不是,则应添加它并配置为映射到外键。然后你可以这样做:

public string SaveInformationToDb(Customerproductdto objDataCollected, List<Productopportunity> objcheckedData)
{
    int  generatedLeadDescriptionId = 0;
    string result = "Failure";

    using (var dbcontext = new LEADSEntities())
    {
            var leadDescription = new LEAD_DESCRIPTION
            {
                DETAIL = objDataCollected.LeadDetails,
                EstimatedRevenue = Convert.ToDecimal(objDataCollected.EstimatedRevenue),
                CustomerContact = objDataCollected.CustomerContact,
                CustomerPhone = objDataCollected.CustomerPhone,
                CustomerEmail = objDataCollected.CustomerEmail
            };

            //process data in the collection
            foreach (var VARIABLE in objcheckedData)
            {
                var leadMetric = new LEAD_METRIC
                {
                    EMPLID = objDataCollected.EmployeeNumber,
                    CustomerNumber = objDataCollected.CustomerNumber,
                    ProductTypeId = GetLeadProductOpportunityId(VARIABLE.ProductName)
                };

                leadDescription.Metrics.Add(leadMetric);
            }
            result = "Success";
            dbcontext.LEAD_DESCRIPTION.Add(leadDescription);
            dbcontext.SaveChanges();
    }
    return result;
}

答案 1 :(得分:1)

你的问题的答案“在每次迭代中调用SaveChanges()是否可以......”是的。有些情况下,您可能希望和/或需要在创建对象后立即将对象保存到数据库,也许您的数据库中有一个触发器,也许下一代代码依赖于现有的先前对象,也许您的集合是非常大并且一次性保存会导致超时。每次迭代调用SaveChanges()是数据库的另一次访问,你必须希望工作正常,可能会给你留下一个部分保存的集合,这是非常错误的。

你的问题的回答“......有更好的方法吗?”这取决于。在大多数情况下,您希望将所有对象添加到上下文中,让Entity Framework处理正确保存的所有内容。

以下是我将使用以下假设更新代码:1。LeadDescriptionId未设置为标识属性2.您没有或无法在LeadDescription和LeadMetric之间创建导航属性

public string SaveInformationToDb(Customerproductdto objDataCollected, List<Productopportunity> objcheckedData)
{
    string result = "Failure";

    using (var dbcontext = new LEADSEntities())
    {
        var leadDescription = new LEAD_DESCRIPTION
        {
            DETAIL = objDataCollected.LeadDetails,
            EstimatedRevenue = Convert.ToDecimal(objDataCollected.EstimatedRevenue),
            CustomerContact = objDataCollected.CustomerContact,
            CustomerPhone = objDataCollected.CustomerPhone,
            CustomerEmail = objDataCollected.CustomerEmail
        };
        dbcontext.LEAD_DESCRIPTION.Add(leadDescription);
        dbcontext.SaveChanges();
        int generatedLeadDescriptionId = leadDescription.ID;

        //process data in the collection
        foreach (var VARIABLE in objcheckedData)
        {
            var leadMetric = new LEAD_METRIC
            {
                EMPLID = objDataCollected.EmployeeNumber,
                CustomerNumber = objDataCollected.CustomerNumber,
                ProductTypeId = GetLeadProductOpportunityId(VARIABLE.ProductName),
                LeadId = generatedLeadDescriptionId
            };
            dbcontext.LEAD_METRIC.Add(leadMetric);

        }
        dbcontext.SaveChanges();
        result = "Success";            
    }
    return result;
}

如果LeadDescriptionId是一个标识属性,您可以在LeadDescription和LeadMetric之间创建导航属性,那么这样的事情应该有效

public string SaveInformationToDb(Customerproductdto objDataCollected, List<Productopportunity> objcheckedData)
{
    string result = "Failure";

    using (var dbcontext = new LEADSEntities())
    {
        var leadDescription = new LEAD_DESCRIPTION
        {
            DETAIL = objDataCollected.LeadDetails,
            EstimatedRevenue = Convert.ToDecimal(objDataCollected.EstimatedRevenue),
            CustomerContact = objDataCollected.CustomerContact,
            CustomerPhone = objDataCollected.CustomerPhone,
            CustomerEmail = objDataCollected.CustomerEmail
        };
        dbcontext.LEAD_DESCRIPTION.Add(leadDescription);

        //process data in the collection
        foreach (var VARIABLE in objcheckedData)
        {
            var leadMetric = new LEAD_METRIC
            {
                EMPLID = objDataCollected.EmployeeNumber,
                CustomerNumber = objDataCollected.CustomerNumber,
                ProductTypeId = GetLeadProductOpportunityId(VARIABLE.ProductName),
                LeadId = generatedLeadDescriptionId
            };
            leadDescription.LEAD_METRIC.Add(leadMetric);
        }

        dbcontext.SaveChanges();
        result = "Success";            
    }
    return result;
}

答案 2 :(得分:-1)

最简单的解决方案是使用另一个DBContext插入实体,该实体将返回Id并在外部上下文中使用此ID

例如

    using (var context = new DatabaseContext())
    {
        ...
        using (var context1 = new DatabaseContext())
        {
            ...
               context1.SaveChanges();
        }                         
        //get id of inserted object from context1 and use is.   
      context.SaveChanges();
   }