C# EF更新实体相关表正在插入而不是更新

C# EF更新实体相关表正在插入而不是更新,c#,entity-framework,C#,Entity Framework,我有一个对象,我正试图使用EntityFramework5更新它 检索现有对象并更新字段后,它将正确更新基本对象“coach”,但无法更新Address对象,而是再次插入它,而不是使用新的主键更新它,即使已将现有主键传递给它以供再次使用 感谢您的帮助 下面是代码的简化版本: using (AltairEntities context = new AltairEntities()) { dtlCoach coa

我有一个对象,我正试图使用EntityFramework5更新它

检索现有对象并更新字段后,它将正确更新基本对象“coach”,但无法更新Address对象,而是再次插入它,而不是使用新的主键更新它,即使已将现有主键传递给它以供再次使用

感谢您的帮助

下面是代码的简化版本:

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