我有两个用EF CodeFirst编写的表:
public class DayType
{
[Key]
public int DayTypeID { get; set; }
public string NameDayType { get; set; }
public virtual ICollection<SpecialDay> Specialdays { get; set; }
public DayType() { }
}
public class SpecialDay
{
[Key]
public int SpecialDayID { get; set; }
public int Year { get; set; }
public int JanuaryDay { get; set; }
public SpecialDay() { }
public int? DayTypeId { get; set; }
public virtual DayType daytype { get; set; }
}
DBContext关系一对多由FluentAPI制作:
modelBuilder.Entity<DayType>().HasMany(p => p.Specialdays).WithOptional(p => p.daytype);
此代码抛出异常。功能的目的是更新实体。虽然调试sd
具有所有属性。 sd - 是从数据网格中选择然后更改的对象。
internal void Update(SpecialDay sd)
{
using (SalDBContext _db = new SalDBContext())
{
var newsd = _db.SpecialDays.FirstOrDefault(p => p.SpecialDayID==sd.SpecialDayID);
newsd.JanuaryDay = sd.JanuaryDay;
....
newsd.DecemberDay = sd.DecemberDay;
newsd.DayTypeId = sd.DayTypeId;
newsd.daytype = sd.daytype;
try
{
_db.SaveChanges();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
此时发生异常_db.SaveChanges();
异常:
{“无法定义两个对象之间的关系,因为它们附加到不同的ObjectContext对象。”} System.Exception {System.InvalidOperationException}
感谢任何有关我的问题的解决方案的帮助。谢谢
答案 0 :(得分:2)
如异常所述,
“无法定义两个对象之间的关系,因为它们附加到不同的ObjectContext对象。”
查看您所拥有的代码,您将从传入的代码中分配daytype
到您从数据库中提取的代码。由于您每次调用SalDBContext
方法时都在创建新的Update
,因此您需要在daytype
个ObjectContext
对象中分配Update
(根据错误消息。
要解决这个问题,您只需要在FirstOrDefault
方法中删除该作业。因为您在属性中分配FK ID,所以您不需要分配对象。
关于EF的另一个注意事项,还有一个Find
方法,它只会由ID代替internal void Update(SpecialDay sd)
{
using (SalDBContext _db = new SalDBContext())
{
var newsd = _db.SpecialDays.Find(p => p.SpecialDayID==sd.SpecialDayID);
newsd.JanuaryDay = sd.JanuaryDay;
....
newsd.DecemberDay = sd.DecemberDay;
newsd.DayTypeId = sd.DayTypeId;
// newsd.daytype = sd.daytype; Must be eliminated!
try
{
_db.SaveChanges();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
。它更加优化了。
ID | Name
1 | Pizza A
2 | Pizza B
3 | Pizza C
答案 1 :(得分:1)
您已将sd
(来自方法主管)与方法正文newsd
中的上下文一起加载。因此,您在调用_db.SaveChanges();
时收到异常。我会在newsd.daytype = sd.daytype;
行说,因为它是一个复杂的数据类型,代表你的一个实体。删除该行并仅设置ID或再次加载obejct sd
以进行引用。
你的修改版本:
internal void Update(SpecialDay sd)
{
using (SalDBContext _db = new SalDBContext())
{
var newsd = _db.SpecialDays.FirstOrDefault(p => p.SpecialDayID==sd.SpecialDayID);
newsd.JanuaryDay = sd.JanuaryDay;
// ...
newsd.DecemberDay = sd.DecemberDay;
// set only the id to reference the object
newsd.DayTypeId = sd.DayTypeId;
// newsd.daytype = sd.daytype;
try
{
_db.SaveChanges();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
嗯,我迟到了几秒钟。 :)