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

时间:2016-01-21 02:38:26

标签: c# entity-framework

我正在尝试使用Entity Framework 5更新对象。

检索现有对象并更新字段后,它会正确更新基础对象“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;
            }
        }

更新: 所以我发现如果我将现有的dtlCoachAddress实体从dtlCoach实体内部作为参数提供给PrepareAddress函数,而不是将对象声明为新的,它会正确更新。 如果我将所有相同的参数传递给实体的dtlCoachAddress对象和从new定义的dtlCoachAddress对象有什么区别?但是这两个定义了对象是否被插入或更新?

1 个答案:

答案 0 :(得分:1)

我不确定您是如何在实体中安排PK和FK的。所以这个解决方案有一些假设。

再次更新以匹配OP方法。

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;
}
}*/