我在实体框架中遇到外键关系问题。我有两个表:Persons
和Countries
。 Persons
有一个CountryId
的外键列。
由于Countries
表很少更改,我只想获取其数据一次,处理DatabaseContext
,并将Countries
列表保存在某处。这是我遇到问题的地方。
实体框架似乎希望您打开数据库上下文,根据需要添加/编辑行,然后关闭数据库上下文。如果你打开,获取数据,关闭;然后打开,保存数据,关闭;它有麻烦。
所以我的POCO对象看起来像这样:
public class Country {
public int CountryId {get; set; }
public String Name {get; set; }
}
public Person {
public int PersonId {get; set; }
public virtual Country Country {get; set; }
}
然后,我尝试创建一个这样的新人:
Country[] countries;
using (var dt = new DatabaseContext())
{
countries= dt.Countries.ToArray();
}
Person person = new Person();
person.Country = countries[0];
using (var dt = new DatabaseContext()) {
dt.Entities.Add(person);
dt.SaveChanges();
}
在保存时,实体框架在Countries
表中创建一个与countries[0]
同名的新行,但是一个新的递增ID。这显然不是理想的结果 - 此人应将其Country_CountryId
字段设置为countries[0]
的ID,并且不应创建新行。
我该如何解决这个问题?我认为一个解决方案是强制实体框架 not 在给定一个已经有其主键集的对象时创建一个新行。有没有办法做到这一点?
答案 0 :(得分:3)
我想知道你是否至少在互联网上搜索一下,然后才付出相当大的努力来描述这个问题,因为这是每隔几天就会发出的一个非常常见的问题。
Add
方法添加实体图中的所有实体。因此,如果您将country
连接到person
并且country
未附加到当前上下文,则Add
上的person
将同时标记person
和country
country
作为插入的新实体。如果您不希望插入country
,则必须告知EF Person person = new Person();
person.Country = countries[0];
using (var dt = new DatabaseContext()) {
dt.Entities.Add(person);
dt.Entry(person.Country).State = EntityState.Modified;
dt.SaveChanges();
}
不是新实体:
{{1}}
答案 1 :(得分:1)
我通过在DatabaseContext
类中添加以下两种方法解决了这个问题:
public void Add(object target)
{
this.Set(target.GetType()).Attach(target);
this.Entry(target).State = System.Data.EntityState.Added;
}
public void Modify(object target)
{
this.Set(target.GetType()).Attach(target);
this.Entry(target).State = System.Data.EntityState.Modified;
}