如何配置EF 4.1以正确建模非标准关系

时间:2011-07-22 15:39:43

标签: entity-framework-4.1 ef-code-first

我有以下不可更改的模型:

Person 
-------
int Id (PK)
int CompanyId
bool Deleted

Company
-------
int Id (PK)
int DefaultIdentifierId

Identifier
-------
int PersonId (PK)
int DefaultIdentifierId (PK)
string Identifier

我已经为每个表创建了类,但我正在努力正确地指定数据库的映射。给定公司ID和Identifer,我需要能够返回未删除人员的Id。在sql中,这将是通过DefaultIdentifierId在Company和Identifer之间的连接,以及通过PersonId在Person和Identifier之间的连接,但我似乎无法正确地指定它。

1 个答案:

答案 0 :(得分:0)

问题是您无法在CompanyIdentifier之间拥有导航属性,因为DefaultIdentifierId中的CompanyDefaultIdentifierId中的Identifier都不是是主键。 (在Identifier中,它只是密钥的一部分。)您可以对CompanyPerson之间以及PersonIdentifier之间的一对多关系建模虽然。所以你可以尝试这些模型类:

public class Person
{
    public int Id { get; set; }
    public int CompanyId { get; set; }
    public Company Company { get; set; }
    public bool Deleted { get; set; }
}

public class Company
{
    public int Id { get; set; }
    public int DefaultIdentifierId { get; set; }
}

public class Identifier
{
    [Key, Column(Order = 1)]
    public int PersonId { get; set; }
    [Key, Column(Order = 2)]
    public int DefaultIdentifierId { get; set; }
    public string IdentifierString { get; set; }

    public Person Person { get; set; }
}

public class MyContext : DbContext
{
    public DbSet<Person> People { get; set; }
    public DbSet<Company> Companies { get; set; }
    public DbSet<Identifier> Identifiers { get; set; }
}

DefaultIdentifierId名称Company中的 ID 会产生误导。在此模型中,此属性是一个简单的标量属性,而不是属于任何导航属性的外键属性。

要运行您想要的查询,您必须在LINQ中使用Join,因为您无法通过导航属性从Company导航到Identifier

int companyId = 1;
string identifierString = "ABC";

List<int> personIds = context.Identifiers
    .Join(context.Companies,
          i => i.DefaultIdentifierId,
          c => c.DefaultIdentifierId,
          (i, c) => new { i, c })
    .Where(a => a.c.Id == companyId 
             && a.i.IdentifierString == identifierString
             && !a.i.Person.Deleted)
    .Select(a => a.i.Person.Id) // or a.i.PersonId should work as well
    .ToList();

结果不一定是唯一的,而是人员ID列表。