C# EF更新实体相关表正在插入而不是更新
我有一个对象,我正试图使用EntityFramework5更新它 检索现有对象并更新字段后,它将正确更新基本对象“coach”,但无法更新Address对象,而是再次插入它,而不是使用新的主键更新它,即使已将现有主键传递给它以供再次使用 感谢您的帮助 下面是代码的简化版本:C# EF更新实体相关表正在插入而不是更新,c#,entity-framework,C#,Entity Framework,我有一个对象,我正试图使用EntityFramework5更新它 检索现有对象并更新字段后,它将正确更新基本对象“coach”,但无法更新Address对象,而是再次插入它,而不是使用新的主键更新它,即使已将现有主键传递给它以供再次使用 感谢您的帮助 下面是代码的简化版本: using (AltairEntities context = new AltairEntities()) { dtlCoach coa
using (AltairEntities context = new AltairEntities())
{
dtlCoach coach = context.dtlCoaches.FirstOrDefault(x => x.CoachID == coachId);
coach.Name = "Bob";
coach.Description = "sample";
coach.dtlCoachAddresses.Add(PrepareAddress(coach.dtlCoachAddresses.First().CoachAddressID));
context.Database.Connection.Open();
context.Entry(coach).State = EntityState.Modified;
context.SaveChanges();
}
public static dtlCoachAddress PrepareAddress(int existingId)
{
dtlCoachAddress newAddress = new dtlCoachAddress();
try
{
newAddress.CoachAddressID = existingId;
newAddress.AddressLine1 = "Line 1";
newAddress.AddressLine2 = "Line 2";
return newAddress;
}
catch (Exception ex)
{
throw ex;
}
}
更新:
因此,我发现,如果我将dtlCoach实体内部的现有dtlCoachAddress实体作为参数馈送到PrepareAddress函数中,而不是将对象声明为新对象,那么它会正确更新。
如果我传递所有相同的参数,那么实体中的dtlCoachAddress对象和从new定义的dtlCoachAddress对象之间有什么区别?但是这两个定义了对象是否被插入或更新?我不确定您在实体中是如何安排PK和FK的。所以这个解决方案有几个假设 再次更新以匹配OPs方法。
using (AltairEntities context = new AltairEntities())
{
dtlCoach coach = context.dtlCoaches.FirstOrDefault(x => x.CoachID == coachId);
coach.Name = "Bob";
coach.Description = "sample";
//coach.dtlCoachAddresses.Add(PrepareAddress(coach.dtlCoachAddresses.First().CoachAddressID));
//context.Database.Connection.Open();
//context.Entry(coach).State = EntityState.Modified;
var address = context.dtlCoachAddresses.FirstOrDefault(a => a.CoachAddressID == coachId);
if(address != null)
{
address.AddressLine1 = "Line 1";
address.AddressLine2 = "Line 2";
}
context.SaveChanges();
}
/*This function is not required
public static dtlCoachAddress PrepareAddress(int existingId)
{
using (AltairEntities context = new AltairEntities())
{
var address = context.dtlCoachAddresses.FirstOrDefault(a => a.CoachAddressID == coachId);
if(address != null)
{
address.AddressLine1 = "Line 1";
address.AddressLine2 = "Line 2";
context.SaveChanges();//update an existing address.
}
}
catch (Exception ex)
{
throw ex;
}
}*/
因此,为了简化您的问题,
coach
得到了正确的更新。该实体没有任何问题。您还需要添加新的地址
。然后将其引用回coach
。但这不起作用。是吗?我想更新地址,而不是添加新地址,并保留对coach的引用。我想从地址表中获取地址,而不是创建新对象,然后将其分配给coach。嗨,Tarik,这是简化版的代码。在上面的场景中,您的解决方案听起来最简单,但在我更复杂的场景中却帮不了我。如果传递相同的主键,则现有上下文的DlcocachAddress与从新上下文创建的DtlocachAddress之间有什么区别@TarikCoachAddressID属于Address对象,包含CoachID的外键,以1-N关系链接回coach对象。dtlCoach表对dtlCoachAddress表有一个约束,因此dtlCoachAddress对象可以从dtlCoach对象获得@科萨拉-w@Nick这是否意味着address.coachaddress==coach.CoachID
?否,地址还包含名为Coach_ID的外键,该外键用作Coach表的约束。这意味着1 coach-多地址关系@科萨拉-w@Nick好啊那么,如何仅通过使用CoachID
找到要更新的地址呢。如果按CoachID
进行筛选,结果可能有多个地址。如果查看我放置的示例代码,它将使用dtlCoachAddress.First()从coach实体中获取第一个地址记录@科萨拉-w