![](/img/trans.png)
[英]Entity framework generic repository - Foreign key exception updating entity relationship
[英]Entity Framework - Updating relationship by changing foreign key
我有以下两个模型和DbContext:
public class TestDbContext : DbContext
{
public IDbSet<Person> People { get; set; }
public IDbSet<Car> Cars { get; set; }
}
public class Person
{
public Person()
{
ID = Guid.NewGuid();
}
public Guid ID { get; set; }
public string Name { get; set; }
public virtual List<Car> Cars { get; set; }
}
public class Car
{
public Car()
{
ID = Guid.NewGuid();
}
public Guid ID { get; set; }
public string Name { get; set; }
public virtual Person Owner { get; set; }
}
然后,我声明人员列表和汽车列表,将第一辆汽车的所有者设置为列表中的第一个人:
List<Person> People = new List<Person>()
{
new Person() {Name = "bill", ID = new Guid("6F39CC2B-1A09-4E27-B803-1304AFDB23E3")},
new Person() {Name = "ben", ID = new Guid("3EAE0303-39D9-4FD9-AF39-EC6DC73F630B")}
};
List<Car> Cars = new List<Car>() { new Car() { Name = "Ford", Owner = People[0], ID = new Guid("625FAB6B-1D56-4F57-8C98-F9346F1BBBE4") } };
我使用以下代码将其保存到数据库中,并且工作正常。
using (TestDbContext context = new TestDbContext())
{
foreach (Person person in People)
{
if (!(context.People.Any(p => p.ID == person.ID)))
context.People.Add(person);
else
{
context.People.Attach(person);
context.Entry<Person>(person).State = System.Data.EntityState.Modified;
}
}
foreach (Car caar in Cars)
{
if (!(context.Cars.Any(c => c.ID == caar.ID)))
context.Cars.Add(caar);
else
{
context.Cars.Attach(caar);
context.Entry<Car>(caar).State = System.Data.EntityState.Modified;
}
}
context.SaveChanges();
}
如果随后我将汽车的所有者更改为第二个人并再次运行代码,则“汽车所有者”属性不会得到更新。
Cars[0].Owner = People[1];
有什么想法我做错了吗? 谢谢你的帮助。
我相信这是独立与外键关联的问题 。 您目前正在使用独立的关联,而汽车与人之间的关系实际上是由具有其自身状态的单独入口对象管理的(要访问此对象,您必须使用ObjectContext API)。 将汽车的实体条目设置为修改状态不会更改该关系的条目状态! 简单的解决方案是使用外键关联,这意味着向您的汽车添加新的Guid PersonId
属性,并将其映射为Person
导航属性的外键属性。
如果您坚持使用独立的关联,则只能更改关联实体上的关联,否则跟踪这些更改并将所有必需的条目设置为正确的状态将非常麻烦。 创建对象并将它们附加到上下文中就足够了,并且只有在这之后设置汽车的所有者-希望它将作为更改进行跟踪。
尝试这样的事情:
using (TestDbContext context = new TestDbContext())
{
foreach (Person person in People)
{
if (!(context.People.Any(p => p.ID == person.ID)))
context.People.Add(person);
else
{
context.People.Attach(person);
context.Entry<Person>(person).State = System.Data.EntityState.Modified;
}
context.SaveChanges();
}
foreach (Car caar in Cars)
{
if (!(context.Cars.Any(c => c.ID == caar.ID)))
context.Cars.Add(caar);
else
{
context.Cars.Attach(caar);
context.Entry<Car>(caar).State = System.Data.EntityState.Modified;
}
context.SaveChanges();
}
}
我认为您的错误是由于context.SaveChanges
位置(以及部分架构)引起的。 考虑通过实体框架对数据库上的每个操作使用专用方法(例如,基本的CRUD)。 希望这可以帮助。
编辑:使用CRUD方法:
public class PersonManager // CRUD
{
public void Create(Person person)
{
using (TestDbContext context = new TestDbContext())
{
context.Person.Add(person);
context.SaveChanges();
}
}
public void Update(Person person)
{
using (TestDbContext context = new TestDbContext())
{
context.Person.Attach(person);
context.Entry(person).State = System.Data.EntityState.Modified;
context.SaveChanges();
}
}
}
您也可以使此类static
,以适应您的体系结构。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.