更新 EF6 中的外键对象
Update Foreign Key Object in EF6
我有以下型号:
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 没有更新 Plaintiffs table 中的现有条目,而是在 Plaintiffs table 中插入了一条新记录,并在 DivorceCases [=] 中更新了这条新记录的外键引用18=]。我究竟做错了什么?我该如何摆脱它?
您要求您的附加案例实体 link 到 未 附加到上下文的项目。
尝试先附上dc.p或干脆在案件上更改原告id而不是更改对象。
不是将 dc.p
分配给 dcold.p
,而是将 dc.p
的属性分配给 dcold.p
的属性,然后调用 SaveChanges();
。您不需要 db.Entry(dcold).State = EntityState.Modified;
entity framework 将更新您的数据而不是创建新条目。试试下面的代码-
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();
经过反复调试命中试验得到解决
首先我做了一个 DBContextExtension Class 这样的:
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();
也许在你的 db.SaveChanges() 调用之前尝试这个..
db.p=db.Plaintiff.Where(x=>x.id==db.p.id);
不确定这是否适用于此。我的数据库结构略有不同。我在链接 table 中存储外键 ID... 我使用传入的值... (...Where(x=>x.id==PlaintiffID)
我有以下型号:
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 没有更新 Plaintiffs table 中的现有条目,而是在 Plaintiffs table 中插入了一条新记录,并在 DivorceCases [=] 中更新了这条新记录的外键引用18=]。我究竟做错了什么?我该如何摆脱它?
您要求您的附加案例实体 link 到 未 附加到上下文的项目。
尝试先附上dc.p或干脆在案件上更改原告id而不是更改对象。
不是将 dc.p
分配给 dcold.p
,而是将 dc.p
的属性分配给 dcold.p
的属性,然后调用 SaveChanges();
。您不需要 db.Entry(dcold).State = EntityState.Modified;
entity framework 将更新您的数据而不是创建新条目。试试下面的代码-
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();
经过反复调试命中试验得到解决
首先我做了一个 DBContextExtension Class 这样的:
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();
也许在你的 db.SaveChanges() 调用之前尝试这个..
db.p=db.Plaintiff.Where(x=>x.id==db.p.id);
不确定这是否适用于此。我的数据库结构略有不同。我在链接 table 中存储外键 ID... 我使用传入的值... (...Where(x=>x.id==PlaintiffID)