实体框架CTP5 Code-First:映射具有另一个类的多个集合的类 [英] Entity Framework CTP5 Code-First: Mapping a class with multiple collections of another class

查看:136
本文介绍了实体框架CTP5 Code-First:映射具有另一个类的多个集合的类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用EF CTP5 Code-First我试图映射一个类模型,其中包含一个类中指向另一个类的多个集合。这是我的意思的一个例子:

  public class Company 
{
public int CompanyId {get ;组; }
public IList< Person>女雇员{get;组; }
public IList< Person>男雇员{get;组; }
}

public class Person
{
public int PersonId {get;组;公司公司{get;组; }
}

如果我让这个模型创建一个 DbContext 没有进一步的自定义,像这样:

  public class MyContext:DbContext 
{
public DbSet< Company>公司{get;组; }
public DbSet< Person>人{get;组; }
}

...然后在SQL Server中得到两个表,一个简单的公司表只包含一个 CompanyId 列和一个 People 以下列(FKRN是指由SQL在SQL Server中创建的外键关系名称):

  PersonId int不可空
CompanyCompanyId int nullable FKRN:Company_FemaleEmployees
CompanyCompanyId1 int nullable FKRN:Company_MaleEmployees
CompanyCompanyId2 int可空FKRN:Person_Company

最后三列与公司的主键 CompanyId 具有外键关系, code>表。



现在我有几个问题:




  • 1)为什么在 People 表格中获得三个外键列?实际上我预计有两个。如果我删除财产 public Company Company {get;组;从 Person 第三栏 CompanyCompanyId2 消失,但我也失去了参考资料这个课程。


  • 2)假设我从公司 > Person table(我不需要它真的在我的模型)。有没有办法给自己创建的 CompanyCompanyId CompanyCompanyId1 的另外一个名称。 (例如 FCompanyId MCompanyId 表示与 FemaleEmployees MaleEmployees collections。)


  • 3)有没有办法只用 People 表中的一个外键 CompanyId 当然,我需要在 Person 类(如 bool IsFemale )中添加一个不同的附加列。一个人是 FemaleEmployees MaleEmployees 集合的一部分,从来都不在这两个(在本例中),所以使用SQL,我可以通过类似 WHERE IsFemale = true / false AND CompanyId = 1 获取这些集合。我想知道如果我可以给EntityFramework提供一个这样加载两个集合的提示。 (这里我想避免使用 FemalePerson MalePerson 类来扩展该模型, $ c> Person 作为基类,然后使用Table-Per-Hierarchy映射,因为这些派生类是空且人工的,除了启用到SQL Server的映射之外,没有其他目的)。只有一个外键 CompanyId 将允许我使用不可空这是不可能用两个外键(两者都不能在同一行中为非空。)




提前感谢您的反馈和建议! / p>

解决方案


  • 提出质疑(1):EF无法映射单个引用属性公司在类 Person 到两个不同的收集端点 FemaleEmployees MaleEmployees 在课程公司同时。映射约定假设在公司中实际上没有在模型中公开的第三个端点。因此,创建了第三个外键。


  • 提问(2):使用 EF 4.1 Release Candidate 现在可以指定数据库列名称通过使用 ForeignKeyNavigationPropertyConfiguration Map 方法,Fluent API中的外键(这不可能与EF CTP5) >类:

      modelBuilder.Entity< Company>()
    .HasMany(c => c.FemaleEmployees)
    .WithOptional()
    .Map(conf => conf.MapKey(FCompanyId))
    .WillCascadeOnDelete(false);

    modelBuilder.Entity< Company>()
    .HasMany(c => c.MaleEmployees)
    .WithOptional()
    .Map(conf => conf.MapKey(MCompanyId))
    .WillCascadeOnDelete(false);


  • 提问(3):我还是不知道。

    li>


修改



只是关闭这个旧问题现在:(3)(将一个实体中的两个导航属性与另一实体的同一端点相关)是不可能的,例如:特定实体框架代码首先多到2个模型映射 ...(和我记得许多其他问题正在寻找一个解决方案对于没有成功的情况)


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 property public Company Company { get; set; } from the Person the third column CompanyCompanyId2 disappears but I also lose the reference property in the class.

  • 2) Let's say I drop the Company property from the Person 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-created CompanyCompanyId and CompanyCompanyId1? (For instance FCompanyId and MCompanyId to indicate the relation to the FemaleEmployees and MaleEmployees collections.)

  • 3) Is there any way to define this model with only one foreign key CompanyId in the People table? Surely I would need a differentiating additional column in the Person class (like bool IsFemale). A Person is either part of the FemaleEmployees or the MaleEmployees collection, never in both (naturally in this example), so with SQL I could fetch those collections by something like WHERE 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 a FemalePerson and MalePerson class which both derive from Person 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 key CompanyId would allow me to make it non-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!

解决方案

  • To question (1): EF cannot map the single reference property Company in class Person to two different collection endpoints FemaleEmployees and MaleEmployees in class Company at the same time. The mapping conventions assume that there is actually a third endpoint in Company 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 the ForeignKeyNavigationPropertyConfiguration class:

    modelBuilder.Entity<Company>()
                .HasMany(c => c.FemaleEmployees)
                .WithOptional()
                .Map(conf => conf.MapKey("FCompanyId"))
                .WillCascadeOnDelete(false);
    
    modelBuilder.Entity<Company>()
                .HasMany(c => c.MaleEmployees)
                .WithOptional()
                .Map(conf => conf.MapKey("MCompanyId"))
                .WillCascadeOnDelete(false);
    

  • 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)

这篇关于实体框架CTP5 Code-First:映射具有另一个类的多个集合的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆