实体框架 CTP5 代码优先:将一个类与另一个类的多个集合映射
使用 EF CTP5 Code-First,我尝试映射一个类模型,该模型在一个类中包含指向另一个类的多个集合。下面是我的意思的一个示例:
public class Company
{
public int CompanyId { get; set; }
public IList<Person> FemaleEmployees { get; set; }
public IList<Person> MaleEmployees { get; set; }
}
public class Person
{
public int PersonId { get; set; }
public Company Company { get; set; }
}
如果我让数据库使用 DbContext
从该模型创建,而无需进一步自定义,如下所示:
public class MyContext : DbContext
{
public DbSet<Company> Companies { get; set; }
public DbSet<Person> People { get; set; }
}
...然后我在 SQL Server 中得到两个表,一个简单的 <仅包含 CompanyId
列的 code>Companies 表和包含以下列的 People
表(“FKRN”表示“外键关系名称”,由SQL Server 中的 EF):
PersonId int not nullable
CompanyCompanyId int nullable FKRN: Company_FemaleEmployees
CompanyCompanyId1 int nullable FKRN: Company_MaleEmployees
CompanyCompanyId2 int nullable FKRN: Person_Company
最后三列与 Companies
表的主键 CompanyId
均具有外键关系。
现在我有几个问题:
1) 为什么我在
People
表中得到三个 外键列?我实际上期望有两个。如果我删除财产public Company Company { get;放; }
从Person
第三列CompanyCompanyId2
消失,但我也丢失了类中的引用属性。2) 假设我从
Person
表中删除了Company
属性(我的模型中实际上并不需要它)。有没有办法为剩下的两个外键列指定一个名称,而不是自动创建的CompanyCompanyId
和CompanyCompanyId1
? (例如,FCompanyId
和MCompanyId
指示与FemaleEmployees
和MaleEmployees
集合的关系。)3 ) 有没有办法在
People
表中仅使用一个外键CompanyId
来定义此模型?当然,我需要在Person
类中添加一个区分的附加列(例如bool IsFemale
)。 Person 要么是FemaleEmployees
的一部分,要么是MaleEmployees
集合的一部分,绝不会同时存在于两者中(在本例中自然如此),因此使用 SQL,我可以通过类似的方式获取这些集合>WHERE IsFemale = true/false AND CompanyId = 1
。我想知道是否可以给 EntityFramework 一个提示,以这种方式加载两个集合。 (在这里,我想避免通过FemalePerson
和MalePerson
类来扩展模型,它们都从Person
派生为基类,然后用于实例每层次结构表映射,因为这些派生类是空的、人为的,除了启用到 SQL Server 的映射之外没有其他用途。)只有一个外键CompanyId
就可以让我做到这一点non-nullable
这对于两个外键是不可能的(同一行中的两个外键永远不能为非空)。
感谢您提前提供反馈和建议!
With EF CTP5 Code-First I am trying to map a class model which contains multiple collections in one class pointing to another class. Here is an example of what I mean:
public class Company
{
public int CompanyId { get; set; }
public IList<Person> FemaleEmployees { get; set; }
public IList<Person> MaleEmployees { get; set; }
}
public class Person
{
public int PersonId { get; set; }
public Company Company { get; set; }
}
If I let the database create from this model with a DbContext
without further customization, like so:
public class MyContext : DbContext
{
public DbSet<Company> Companies { get; set; }
public DbSet<Person> People { get; set; }
}
... then I get two tables in SQL Server, a simple Companies
table with only a CompanyId
column and a People
table with the following columns ("FKRN" means "Foreign Key Relationship Name", as created by EF in SQL Server):
PersonId int not nullable
CompanyCompanyId int nullable FKRN: Company_FemaleEmployees
CompanyCompanyId1 int nullable FKRN: Company_MaleEmployees
CompanyCompanyId2 int nullable FKRN: Person_Company
The last three columns have all a foreign key relationship to the primary key CompanyId
of the Companies
table.
Now I have several questions:
1) Why do I get three foreign key columns in the
People
table? I actually expected two. If I remove the propertypublic Company Company { get; set; }
from thePerson
the third columnCompanyCompanyId2
disappears but I also lose the reference property in the class.2) Let's say I drop the
Company
property from thePerson
table (I don't need it really in my model). Is there a way to give the two remaining foreign key columns another name than the auto-createdCompanyCompanyId
andCompanyCompanyId1
? (For instanceFCompanyId
andMCompanyId
to indicate the relation to theFemaleEmployees
andMaleEmployees
collections.)3) Is there any way to define this model with only one foreign key
CompanyId
in thePeople
table? Surely I would need a differentiating additional column in thePerson
class (likebool IsFemale
). A Person is either part of theFemaleEmployees
or theMaleEmployees
collection, never in both (naturally in this example), so with SQL I could fetch those collections by something likeWHERE IsFemale = true/false AND CompanyId = 1
. I am wondering if I could give EntityFramework a hint to load the two collections this way. (Here I would like to avoid to extend the model by aFemalePerson
andMalePerson
class which both derive fromPerson
as base class and then use for instance Table-Per-Hierarchy mapping, since these derived classes would be empty and artificial and had no other purpose except enabling the mapping to SQL Server.) Having only one foreign keyCompanyId
would allow me to make itnon-nullable
which isn't possible with two foreign keys (both can never be non-null in the same row).
Thank you for feedback and suggestions in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
对于问题 (1):EF 无法将类
Person
中的单个引用属性Company
映射到两个不同的集合端点FemaleEmployees
和MaleEmployees
同时位于Company
类中。映射约定假设Company
中实际上存在第三个端点,该端点未在模型中公开。因此,创建了第三个外键。对于问题 (2):使用 EF 4.1 候选版本 现在可以使用
在 Fluent API 中指定外键的数据库列名称(这在 EF CTP5 中是不可能的)
方法:ForeignKeyNavigationPropertyConfiguration
类的 Map对于问题 (3):我仍然不知道。
编辑
现在只是为了结束这个老问题:(3)(将一个实体中的两个导航属性与另一个实体的同一端点相关)是不可能的,例如:特定实体框架代码优先多对2模型映射 .. (我记得许多其他问题正在为这种情况寻找解决方案,但没有成功)
To question (1): EF cannot map the single reference property
Company
in classPerson
to two different collection endpointsFemaleEmployees
andMaleEmployees
in classCompany
at the same time. The mapping conventions assume that there is actually a third endpoint inCompany
which isn't exposed in the model. Therefore a third foreign key is created.To question (2): With the EF 4.1 Release Candidate it is now possible to specify the database column name of foreign keys in the Fluent API (which wasn't possible with EF CTP5) by using the
Map
method of theForeignKeyNavigationPropertyConfiguration
class:To question (3): I still have no idea.
Edit
Just to close this old question now: (3) (relating two navigation properties in one entity to the same endpoint of another entity) is not possible, for example: Specific Entity Framework Code First Many to 2 Model Mapping ... (and I remember many other questions which were looking for a solution for such a scenario without success)
我认为你可以这样做:
你在 People 表上只有一个 CompanyID FK。
您可以使用 EF 上下文加载男性员工:
我认为您的方法不太好,因为,当我将男性添加到 Company.FemaleEmployees 时会发生什么? EF不知道这个规则
I think you could do this:
You just have one CompanyID FK at People table.
You can load Male Employees using EF context:
I think that your approach isn´t so good, because, what happens when I add a male to Company.FemaleEmployees? EF dont know this rules