我有以下方法,即将数据写入数据库中的两个表。我需要写一个集合 到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;
}
答案 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();
}