【问题标题】:Update Foreign Key Object in EF6更新 EF6 中的外键对象
【发布时间】:2016-05-14 06:40:19
【问题描述】:

我有以下型号:

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 表中这条新记录的外键引用。我究竟做错了什么?我该如何摆脱它?

【问题讨论】:

  • 你展示了整个课程吗?我认为这可能与构造函数中的初始化代码有关。
  • @GertArnold 不,先生,这不是整个班级。实际上,就我而言,我已经得到了我在下面发布的解决方案。

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


【解决方案1】:

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

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

【讨论】:

  • 请您详细说明一下先生。我没听懂你的话。
  • db.Plaintiff.Attach(dc.p);
【解决方案2】:

不要将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();

【讨论】:

    【解决方案3】:

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

    首先我创建了一个这样的 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;
        }
    

    然后对于每个外键引用的对象,我调用了这个扩展方法,并获得了 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();
    

    【讨论】:

      【解决方案4】:

      也许在你调用 db.SaveChanges() 之前试试这个。

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-07
        • 1970-01-01
        相关资源
        最近更新 更多