1

我在实体框架中遇到外键关系问题。我有两张桌子:PersonsCountriesPersons有一个外键列到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字段应该设置为 id countries[0],并且不应该创建一个新行。

我该如何解决这个问题?我认为一种解决方案是强制实体框架在给定一个已经设置了主键的对象时不创建新行。有没有办法做到这一点?

4

2 回答 2

3

我想知道你是否至少在互联网上搜索一下,然后再花很大的力气描述这个问题,因为这是每隔几天就会被问到的非常常见的问题。

Add方法在实体图中添加所有实体。因此,如果您连接country到当前上下文person并且country未附加到当前上下文,则调用Add会将两者person标记为新实体以进行插入。如果您不想被插入,您必须告诉 EF 这不是一个新实体:personcountrycountrycountry

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();
}
于 2012-04-16T10:44:12.993 回答
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;
}
于 2012-04-16T11:40:07.323 回答