更新EF6中的外键对象

时间:2016-05-14 06:40:19

标签: c# asp.net asp.net-mvc linq-to-entities entity-framework-6

我有以下模特:

public class DivorceCases
{
  [Key]
  [Required]
  public string case_id { get; set; }
  public string archived { get; set; }
  public virtual Plaintiff p { get; set; }
}

public class Plaintiff{
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int id { get; set; }
    public string name { get; set; }
}

我正在使用DivorceCases的ModelView进行编辑,在控制器中,我正在使用:

DivorceCases dcold = db.DivorceCase.Where(x => x.case_id == dc.case_id).Include(x => x.p).SingleOrDefault();
            dcold.p = dc.p;
            db.Entry(dcold).State = EntityState.Modified;
            db.SaveChanges();

当我更新时,EF6不会更新原告表中的现有条目,而是在原告表中插入新记录,并在DivorceCases表中更新此新记录的外键引用。我究竟做错了什么?我该如何摆脱它?

4 个答案:

答案 0 :(得分:0)

您要求您的附加案例实体链接到附加到上下文的项目。

首先尝试附加 dc.p ,或者只是更改案例中的原告ID,而不是更改对象。

答案 1 :(得分:0)

不是将dc.p分配给dcold.p,而是将dc.p的属性分配给dcold.p的属性,然后调用SaveChanges();。您不需要db.Entry(dcold).State = EntityState.Modified;实体框架将更新您的数据而不是创建新条目。请尝试以下代码 -

    DivorceCases dcold = db.DivorceCase.Where(x => x.case_id == dc.case_id)
            .Include(x => x.p).SingleOrDefault();
            dcold.p.name = dc.p.name;
            db.SaveChanges();

答案 2 :(得分:0)

经过反复调试和点击试验,我得到了一个解决方案。

首先,我创建了一个DBContextExtension类,如下所示:

public static T Modify<T>(this T t,T tnew)
    {
        PropertyInfo[] properties = typeof(T).GetProperties();
        foreach (PropertyInfo property in properties)
        {
            if (property.Name != "id" && (property.PropertyType==typeof(string) || property.PropertyType==typeof(DateTime)))
            {
                if (property.GetValue(tnew) != null)
                property.SetValue(t, property.GetValue(tnew));
            }
        }
        return t;
    }

然后,对于每个外键引用对象,我调用了此Extension方法并获得了100%的成功。

DivorceCases dcold = db.DivorceCase.Where(x => x.case_id == dc.case_id).Include(x => x.p).SingleOrDefault();
            dcold = dcold.Modify(dc);
            dcold.p = dcold.p.Modify(dc.p);
            dcold.d = dcold.d.Modify(dc.d);
            db.SaveChanges();

答案 3 :(得分:0)

也许在您的db.SaveChanges()调用之前尝试一下。

 db.p=db.Plaintiff.Where(x=>x.id==db.p.id);

不确定在这里是否可以使用。我的数据库结构略有不同。我将外键ID存储在链接表中...我使用传入的值...(...((x => x.id == PlaintiffID)