[英]Entity Framework Code First Two navigationProperty to/from one abstract entity
The following entities is my code first which PersonParameter is an abstract class and Shirt and Shoes are inherited from it with typ(1,2)以下实体首先是我的代码,其中 PersonParameter 是一个抽象类,而 Shirt 和 Shoes 是从它继承而来的 typ(1,2)
[Table("Person")]
public class Person
{
[Key]
public int id { get; set; }
public string Name { get; set; }
public int? shirtID { get; set; }
public int? shoesID { get; set; }
[ForeignKey("shirtID")]
public Shirt Shirt { get; set; }
[ForeignKey("shoesID")]
public Shoes Shoes { get; set; }
}
[Table("PersonParameter")]
public abstract class PersonParameter
{
public int id { get; set; }
public string Title { get; set; }
public string Value { get; set; }
public List<Person> Persons { get; set; }
}
public class Shirt : PersonParameter
{
}
public class Shoes : PersonParameter
{
}
and for model dbcontext和模型 dbcontext
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<PersonParameter>()
.Map<Shirt>(p => p.Requires("typ").HasValue(1))
.Map<Shoes>(p => p.Requires("typ").HasValue(2));
}
but the above codes will create unwanted field PersonParameter_id in Person table:但是上面的代码会在 Person 表中创建不需要的字段 PersonParameter_id :
public override void Up()
{
CreateTable(
"dbo.PersonParameter",
c => new
{
id = c.Int(nullable: false, identity: true),
Title = c.String(),
Value = c.String(),
typ = c.Int(nullable: false),
})
.PrimaryKey(t => t.id);
CreateTable(
"dbo.Person",
c => new
{
id = c.Int(nullable: false, identity: true),
Name = c.String(),
shirtID = c.Int(),
shoesID = c.Int(),
PersonParameter_id = c.Int(),
})
.PrimaryKey(t => t.id)
.ForeignKey("dbo.PersonParameter", t => t.shirtID)
.ForeignKey("dbo.PersonParameter", t => t.shoesID)
.ForeignKey("dbo.PersonParameter", t => t.PersonParameter_id)
.Index(t => t.shirtID)
.Index(t => t.shoesID)
.Index(t => t.PersonParameter_id);
}
how can I solve it (PersonParameter_id) I did some FluentApi with HasOptional.WithMany but didn't solve.我该如何解决它(PersonParameter_id)我用 HasOptional.WithMany 做了一些 FluentApi 但没有解决。
EDIT编辑
After some test, found that for non abstract class it create extra id too and the one solution for fixing that issue is removing navigation property from parameter class and adding it to the inheritance classes (shirt and shoes)经过一些测试,发现对于非抽象类,它也会创建额外的 id,解决该问题的一种解决方案是从参数类中删除导航属性并将其添加到继承类(衬衫和鞋子)中
The reason you end up with one additional FK on Persons table is because of the Persons property on PersonParameter class.您最终在 Persons 表上多了一个 FK 的原因是因为 PersonParameter 类上的 Persons 属性。 Basically EF cannot relate that to any of the current two relationships defined (Shirt and Shoes) and figured that Persons property must have been a third relationship between Persons and PersonParamter tables and therefore creates a third FK (PersonParameter_id) to create this relationship.基本上 EF 无法将其与当前定义的两个关系(衬衫和鞋子)中的任何一个相关联,并认为 Persons 属性必须是 Persons 和 PersonParamter 表之间的第三种关系,因此创建了第三个 FK (PersonParameter_id) 来创建这种关系。 As a result, you end up with 3 uni-directional Many to One relationships from PersonParameter to Persons.因此,您最终会得到 3 个从 PersonParameter 到 Persons 的单向多对一关系。
To fix this, you need to explicitly tell EF that Persons is in fact the Inverse Property of Shoes and Shirts since there is no way that EF can pick that up automatically.要解决此问题,您需要明确告诉 EF Persons 实际上是鞋子和衬衫的逆属性,因为 EF 无法自动获取它。 You can do that with fluent API or by Annotations like this:您可以使用 fluent API 或通过这样的注释来做到这一点:
[Table("PersonParameter")]
public abstract class PersonParameter
{
public int id { get; set; }
public string Title { get; set; }
public string Value { get; set; }
}
public class Shirt : PersonParameter
{
[InverseProperty("Shirt")]
public List<Person> Persons { get; set; }
}
public class Shoes : PersonParameter
{
[InverseProperty("Shoes")]
public List<Person> Persons { get; set; }
}
You can also achieve this by using the Fluent API:您还可以使用 Fluent API 来实现这一点:
modelBuilder.Entity<Shirt>()
.HasMany(s => s.Persons)
.WithOptional(p => p.Shirt)
.HasForeignKey(p => p.shirtID);
modelBuilder.Entity<Shoes>()
.HasMany(s => s.Persons)
.WithOptional(p => p.Shoes)
.HasForeignKey(p => p.shoesID);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.