实体框架code首先多到多关系和继承 [英] Entity Framework Code First Many-to-Many relationship and inheritance
问题描述
原谅我,如果这个问题已经回答了什么地方,我一直有一个很难找到这个问题的解决方案。
Forgive me if this question has been answered somewhere, I have been having a hard time finding a solution for this problem.
我试图建立EF code首先在一个MVC4项目。我有一个用户和客户,无论从Person继承。然后,我有一个与客户多对多关系,并与用户的一到多关系模板对象。这是我如何有它设置:
I am trying to set up EF Code First on an MVC4 Project. I have a User and Customer that both inherit from Person. I then have a Template object that has a Many-to-Many relationship with Customer and a One-to-Many relationship with User. Here is how I have it set up:
模型
public class Person
{
[Key]
public int PersonID { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public string FullName
{
get
{
return String.Format("{0} {1}", FirstName, LastName);
}
}
public string Email { get; set; }
public virtual List<Template> Templates { get; set; }
}
public class User : Person
{
....
}
public class Customer : Person
{
....
}
public class Template
{
public int TemplateId { get; set; }
public string TemplateName { get; set; }
public virtual List<Customer> Customers { get; set; }
[ForeignKey("User")]
public int UserId { get; set; }
public virtual User User { get; set; }
}
背景
public class ProjectContext : DbContext
{
public ProjectContext()
: base("name=ProjectDB")
{
}
public DbSet<Template> Templates { get; set; }
public DbSet<User> Users { get; set; }
public DbSet<Customer> Customers { get; set; }
public DbSet<Person> People { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions
.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<Template>()
.HasMany(x => x.Customers)
.WithMany(x => x.Templates)
.Map(x => x.MapLeftKey("TemplateId")
.MapRightKey("PersonId")
.ToTable("TemplateCustomer")
);
}
}
如果我删除的人DBSet出的背景下能正常工作,但设置了TPT的继承。我想用TPH继承,但是当我能在上下文的人DBSet迁移它闷死了:
If I remove the Person DBSet out of the context this works fine but sets up TPT inheritance. I would like to use TPH inheritance, but when I enable migrations with the Person DBSet in the context it chokes:
NavigationProperty'模板'是无效的。 FromRole在AssociationTypeMvcProject.Models.Template_Customers'Template_Customers_Target'类型'MvcProject.Models.Customer必须完全匹配与此NavigationProperty声明的类型'MvcProject.Models.Person'。
NavigationProperty 'Templates' is not valid. Type 'MvcProject.Models.Customer' of FromRole 'Template_Customers_Target' in AssociationType 'MvcProject.Models.Template_Customers' must exactly match with the type 'MvcProject.Models.Person' on which this NavigationProperty is declared on.
我在哪里去错在这里?
推荐答案
您不能继承的从基实体导航属性的。他们总是必须的声明的关系中的另一端指的是类。
You cannot inherit navigation properties from a base entity. They always must be declared in the class the other end of the relationship is refering to.
-
Template.Customers
是指的客户
(不是人
),因此逆导航属性模板
必须在客户
(不是人
) -
Template.User
是指的用户
(不是人
),因此逆导航属性模板
必须在用户
(不是人
)
Template.Customers
is refering toCustomer
(not toPerson
), hence the inverse navigation propertyTemplates
must be declared inCustomer
(not inPerson
)Template.User
is refering toUser
(not toPerson
), hence the inverse navigation propertyTemplates
must be declared inUser
(not inPerson
)
所以,基本上,你必须从人
移动模板
收集到两个派生类:
So, basically you must move the Templates
collection from Person
into both derived classes:
public class Person
{
// no Templates collection here
}
public class User : Person
{
//...
public virtual List<Template> Templates { get; set; }
}
public class Customer : Person
{
//...
public virtual List<Template> Templates { get; set; }
}
然后,你可以定义像这样流利的API的两个关系:
Then you can define the two relationships with Fluent API like so:
modelBuilder.Entity<Template>()
.HasMany(t => t.Customers)
.WithMany(c => c.Templates) // = Customer.Templates
.Map(x => x.MapLeftKey("TemplateId")
.MapRightKey("PersonId")
.ToTable("TemplateCustomer"));
modelBuilder.Entity<Template>()
.HasRequired(t => t.User)
.WithMany(u => u.Templates) // = User.Templates
.HasForeignKey(t => t.UserId);
这篇关于实体框架code首先多到多关系和继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!