Entity framework 具有泛型对象类型的Fluent API复合外键

Entity framework 具有泛型对象类型的Fluent API复合外键,entity-framework,entity-framework-4.1,ef-code-first,fluent-interface,Entity Framework,Entity Framework 4.1,Ef Code First,Fluent Interface,我有一个Organization类和一个User类,如下所示,&我希望能够分别为每个类分配一个地址,而无需为AddressUser和AddressOrganization、AddressAnything分配两个单独的多对多表,等。原因是我可能有多个实体,我想分配一个地址给&不希望每个需要地址记录的实体都有一个中间连接表 我也不想为每个需要关联地址的实体存储Address.OrganizationId或Address.UserId之类的外键 Fluent API或代码优先数据注释是否有一种方法可以

我有一个Organization类和一个User类,如下所示,&我希望能够分别为每个类分配一个地址,而无需为AddressUser和AddressOrganization、AddressAnything分配两个单独的多对多表,等。原因是我可能有多个实体,我想分配一个地址给&不希望每个需要地址记录的实体都有一个中间连接表

我也不想为每个需要关联地址的实体存储Address.OrganizationId或Address.UserId之类的外键

Fluent API或代码优先数据注释是否有一种方法可以容纳某种具有对象类型的复合泛型外键

像DomainObjectType表吗

域对象类型:

公共类DomainObjectType
{
[关键]
public int Id{get;set;}//种子
公共字符串ObjectType{get;set;}//用户或组织
}
DomainObjectType的种子将为:

var objTypes=新列表
{ 
新域ObjectType(){Id=1,ObjectType=“User”},
新域ObjectType(){Id=2,ObjectType=“Organization”}
};
ForEach(c=>context.DomainObjectTypes.Add(c));
SaveChanges();
组织机构:

公共类组织
{    
//主键
[关键]
公共int Id{get;set;}
公共字符串名称{get;set;}
公共字符串说明{get;set;}
#区域导航属性
公共虚拟ICollection用户{get;set;}
公共虚拟ICollection地址{get;set;}
#端区
}
用户

公共类用户
{
[关键]
公共int Id{get;set;}
公共字符串名{get;set;}
公共字符串LastName{get;set;}
public int OrganizationId{get;set;}
[外键(“组织ID”)]
公共虚拟组织{get;set;}
公共虚拟ICollection地址{get;set;}
}
地址

公共类地址
{
//主键
公共int Id{get;set;}
公共字符串地址1{get;set;}
公共字符串地址2{get;set;}
公共字符串City{get;set;}
公共字符串状态{get;set;}
公共字符串Zip{get;set;}
公共字符串地址类型{get;set;}
#区域外键
//对此不完全确定?(可能移动到多对多“联接”表)
public int DomainObjectId{get;set;}//Composite key;将是OrganizationId或UserId
公共字符串DomainObjectTypeId{get;set;}//复合键
#端区
#区域导航属性
公共虚拟ICollection组织{get;set;}
公共虚拟ICollection用户{get;set;}
#端区
}
流畅的API素材:

模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
//首先配置代码以忽略PluralizingTableName约定
//如果保持此约定,则生成的表将具有复数名称。
modelBuilder.Conventions.Remove();
//一对多组织对用户
modelBuilder.Entity()
.HasRequired(u=>u.Organization)
.WithMany(o=>o.Users)
.HasForeignKey(u=>u.OrganizationId);
//这里的泛型AddressDomainObjectType是什么?
}

通过为这些“其他实体”创建基类,您可以实现您想要的功能—在
地址
和“其他实体”之间只有一个多对多表,例如:

public abstract class DomainObjectWithAddresses
{
    public int Id { get; set; }

    public virtual ICollection<Address> Addresses { get; set; }
}

public class User : DomainObjectWithAddresses
{
    // other properties but without Id which is inherited from base class
}

public class Organization : DomainObjectWithAddresses
{    
    // other properties but without Id which is inherited from base class
}

public class Address
{
    public int Id { get; set; }
    // other properties

    public virtual ICollection<DomainObjectWithAddresses> DomainObjects
                                                                 { get; set; }
}

我不喜欢它。我更愿意为与地址有多对多关系的每种类型引入多个联接表。我怀疑仅仅为了在数据库中保存几个表而在域模型中引入抽象是一个好主意。这个抽象的
DomainObjectWithAddresses
类是一个非常技术性的(“表节省助手”)工件,在您的域模型中没有任何有价值的意义。对我来说,说用户有地址,组织有地址,而不是说用户是有地址的对象,组织是有地址的对象,听起来更自然。从长远来看,这只会使使用您的模型变得复杂。

地址
用户
之间以及
地址
组织
之间是否存在多对多关系?您在开始时这样说,但您的模型草图看起来不像多对多。您的模型就像@Slauma所说的那样令人困惑-但您可能只需要以下
。HasForeignKey(i=>new{i.DomainObjectId,i.DomainObjectTypeId})
用于
地址
表,我猜。更正了我的User&Address类以指示多对多。看起来我可能需要一个多对多的毕竟-AddressDomainObjectType?我想我正试图像NSGaga所建议的那样把我需要的所有东西都放在地址表中,但是在回顾了我的模型之后,正如你们所指出的,我不想要多个多对多的表(即AddressUser或AddressOrganization或AddressAnything)。我想要一个多对多表,其复合外键中包含DomainObjectTypeId。只是不知道如何用Fluent API或我的模型来表达。你解决了我的问题,但把我引向了另一个方向-哇,谢谢你的诚实观察。我同意,我确实开始觉得我把这里的事情复杂化了,尽管我在技术上可以做到这一点。我会接受你的答案,但是使用额外的多个联接表。我试图为我的实体创建相同的基类(与我处理现有数据库时的复杂性不同),然后我
modelBuilder.Entity<DomainObjectWithAddresses>()
    .HasMany(d => d.Addresses)
    .WithMany(a => a.DomainObjects)
    .Map(x =>
    {
        x.ToTable("DomainObjectAddresses");
        x.MapLeftKey("DomainObjectId");
        x.MapRightKey("AddressId");
    });

modelBuilder.Entity<User>()
    .ToTable("Users");           // TPT inheritance mapping

modelBuilder.Entity<Organization>()
    .ToTable("Organizations");   // TPT inheritance mapping
public DbSet<DomainObjectWithAddresses> DomainObjects { get; set; }