C# 实体框架&x27;s AddOrUpdate导致不正确的外键更新
假设我有许多国家,每个国家都有许多城市。我可以使用以下模型来表示这一点:C# 实体框架&x27;s AddOrUpdate导致不正确的外键更新,c#,entity-framework,C#,Entity Framework,假设我有许多国家,每个国家都有许多城市。我可以使用以下模型来表示这一点: public class Country { public virtual int Id { get; set; } [Required] public virtual string Name { get; set; } public virtual ICollection<City> Cities { get; set; } } public class City {
public class Country
{
public virtual int Id { get; set; }
[Required]
public virtual string Name { get; set; }
public virtual ICollection<City> Cities { get; set; }
}
public class City
{
public virtual int Id { get; set; }
[Required]
public virtual string Name { get; set; }
public virtual Country Country { get; set; }
public virtual int CountryId { get; set; }
}
class TestContext : DbContext
{
public DbSet<City> Cities { get; set; }
public DbSet<Country> Countries { get; set; }
}
公共类国家
{
公共虚拟整数Id{get;set;}
[必需]
公共虚拟字符串名称{get;set;}
公共虚拟ICollection城市{get;set;}
}
公营城市
{
公共虚拟整数Id{get;set;}
[必需]
公共虚拟字符串名称{get;set;}
公共虚拟国家{get;set;}
公共虚拟int CountryId{get;set;}
}
类TestContext:DbContext
{
公共数据库集城市{get;set;}
公共数据库集国家{get;set;}
}
实体框架正确识别外键并生成表
但是,如果我现在尝试播种一些测试数据:
static class Program
{
static void Main()
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<TestContext>());
using (var db = new TestContext())
{
db.Database.Initialize(true);
db.Database.Log = Console.Write;
var country = db.Countries.Create();
country.Name = "France";
db.Countries.AddOrUpdate(a => a.Name, country);
var city = db.Cities.Create();
city.Name = "Paris";
city.Country = country;
db.Cities.AddOrUpdate(q => q.Name, city);
db.SaveChanges();
}
}
}
静态类程序
{
静态void Main()
{
SetInitializer(新的DropCreateDatabaseIfModelChanges());
使用(var db=newtestcontext())
{
db.Database.Initialize(true);
db.Database.Log=Console.Write;
var country=db.Countries.Create();
country.Name=“法国”;
db.Countries.AddOrUpdate(a=>a.Name,country);
var city=db.Cities.Create();
city.Name=“巴黎”;
城市。国家=国家;
db.Cities.AddOrUpdate(q=>q.Name,city);
db.SaveChanges();
}
}
}
第一次运行时,一切正常,数据库中的CountryId字段设置正确。但是,当我第二次运行它时,db.SaveChanges()
试图将Paris的CountryId设置为0,这违反了不可为空的外键约束
问题似乎是,尽管城市
和国家
是变更跟踪代理,但国家ID
属性从未更新。不过,手动更新并没有帮助
这是预期的行为吗?如果是,我如何使用AddOrUpdate
,而不进行这样的更改?通过设置外键来执行所有操作似乎不是一个选项,因为这些外键在代码第一次运行时不可用。也许您需要这个
[Key]
public virtual int Id { get; set; }
AFAIK
AddOrUpdate
不支持导航属性。另外,当AddOrUpdate
未通过输入获取任何属性时,它将使用属性的默认值保存该属性
city.Name = "Paris";
city.Country = country;
在您的调查中,您使用导航属性
city.Name = "Paris";
city.Country = country;
但是,AddOrUpdate
由于缺少支持导航属性,所以在内部没有分配city.CountryId=country.Id
。因此,您的city.CountryId
值变为0,这是int的默认值
您应该自己分配外键
var city = db.Cities.Create();
city.Name = "Paris";
city.Country = country;
db.Cities.AddOrUpdate(q => q.Name, city);
应该是这样的
var city = db.Cities.Create();
city.Name = "Paris";
city.Country = country;
//Assign foreign key by manually.
city.CountryId = country.Id;
db.Cities.AddOrUpdate(q => q.Name, city);
我没有测试它