C# 实体框架:代码中的外键优先
我的代码中有什么错误,错误如下: 无法确定从属操作的有效顺序。依赖关系可能由于外键约束、模型要求或存储生成的值而存在 代码: 类别食物:C# 实体框架:代码中的外键优先,c#,entity-framework,foreign-keys,entity-framework-6,code-first,C#,Entity Framework,Foreign Keys,Entity Framework 6,Code First,我的代码中有什么错误,错误如下: 无法确定从属操作的有效顺序。依赖关系可能由于外键约束、模型要求或存储生成的值而存在 代码: 类别食物: public class Food { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public short Id { get; set; } //some Property public string Name { get; set; }
public class Food
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public short Id { get; set; }
//some Property
public string Name { get; set; }
public virtual ICollection<Person> Persons { get; set; }
}
班长:
public class Person
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
//some Property
public string FirstName { get; set; }
[ForeignKey("BestFoodId")]
public Food BestFood { get; set; }
public short BestFoodId { get; set; }
public virtual ICollection<Food> FavoriteFoods { get; set; }
}
种子法:
protected override void Seed(MyContext context)
{
Food food1 = new Food() { Name = "foo1" };
Food food2 = new Food() { Name = "foo2" };
Food food3 = new Food() { Name = "foo3" };
context.Persons.AddOrUpdate(new Person()
{
FirstName = "Jack",
BestFood = food2,
FavoriteFoods = new List<Food>() { food1, food2, food3 }
});
}
看起来您有一个循环依赖项 答案如下: 可选改进: 你应该申报你的身份 如果您使用的是C 6.0或更高版本,请将数据注释定义更改为[ForeignKey[nameofBestFoodId],以避免硬编码属性名称出现错误。这是一个非常酷的编译器功能!:
看起来您有一个循环依赖项 答案如下: 可选改进: 你应该申报你的身份 如果您使用的是C 6.0或更高版本,请将数据注释定义更改为[ForeignKey[nameofBestFoodId],以避免硬编码属性名称出现错误。这是一个非常酷的编译器功能!: 错误原因:关联混乱 这是因为根据惯例,实体框架假定Person.BestFoodId的反向属性为Food.Persons。以不同的方式表述:Person.BestFood和Food.Persons被假定为一对多关联的两端,将Person.BestFoodId作为外键 您可以通过向BestFood添加[InverseProperty]属性来验证: 这会导致相同的错误 此错误-无有效订购-始终表示存在鸡肉和鸡蛋问题。在您的情况下,EF尝试插入食物,需要插入人的生成Id作为外键,而插入人需要插入食物2的生成Id 解决方案:显式映射关联 事实上,人和食物有两种联系: 1-n:食物可以是n个人最好的食物。 n-m:n食物可能是m人最喜欢的食物。 在您的模型中,BestFood没有反向属性,这可能是
public virtual ICollection<Person> BestFoodOf { get; set; }
我已经注释掉了WillCascadeOnDeletefalse。你要么添加这一行,要么添加
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
…以防止SQL Server限制中出现多个级联删除路径
有了这一点,EF知道如何确定插入的有效顺序:它将首先插入食物,然后使用生成的foo2 Id作为外键插入人员,然后在PersonFavoriteFood表中插入连接记录。错误原因:混淆关联
这是因为根据惯例,实体框架假定Person.BestFoodId的反向属性为Food.Persons。以不同的方式表述:Person.BestFood和Food.Persons被假定为一对多关联的两端,将Person.BestFoodId作为外键
您可以通过向BestFood添加[InverseProperty]属性来验证:
这会导致相同的错误
此错误-无有效订购-始终表示存在鸡肉和鸡蛋问题。在您的情况下,EF尝试插入食物,需要插入人的生成Id作为外键,而插入人需要插入食物2的生成Id
解决方案:显式映射关联
事实上,人和食物有两种联系:
1-n:食物可以是n个人最好的食物。
n-m:n食物可能是m人最喜欢的食物。
在您的模型中,BestFood没有反向属性,这可能是
public virtual ICollection<Person> BestFoodOf { get; set; }
我已经注释掉了WillCascadeOnDeletefalse。你要么添加这一行,要么添加
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
…以防止SQL Server限制中出现多个级联删除路径
有了这一点,EF知道如何确定插入的有效顺序:它将首先插入食物,然后使用生成的Food2 Id作为外键插入人员,然后在PersonFavoriteFood表中插入连接记录。感谢您的关注;欢迎您,我的朋友!但我希望我能够在以下方面帮助您至少一点;你们很棒。在提问之前,我仔细阅读了几篇教程,但每个场景对自己都有好处,我无法解决我的问题。我的问题的代码非常简单。Evrey body轻松地测试它和你们的答案。感谢你们的关注;欢迎你们成为我的朋友!但我希望我至少能帮你们一点忙;你很好。在提问之前,我仔细阅读了几篇教程,但每个场景都对自己有利,我无法解决我的问题。我的问题代码非常简单。Evrey body轻松地测试它和你的答案。