0

以下是使用 EF 5.0.0-rc 和 Code First。在我的设计中,我有一个属性实体:

public class Attribute
{ 
    public int AttributeId { get; set; }
    public Guid Guid { get; set; }
    public string Name { get; set; }
    public string Value { get; set; }

    /* Used for testing the first fluent statement */
    public virtual ICollection<Customer> Customers { get; set; }
}

我还有多个包含 GUID 的实体:

public class Customer
{ 
    public int CustomerId { get; set; }
    public Guid Guid { get; set; }
}

public class Location
{ 
    public int LocationId { get; set; }
    public Guid Guid { get; set; }
}

我希望属性表对客户表和位置表都是通用的,中间没有列或表。我似乎无法在流畅的 API 中获得正确的映射来创建没有帮助表的 FK:

        modelBuilder.Entity<Customer>()
            .HasMany(o => o.Attributes)
            .WithMany(o => o.Customers)
            .Map(m => m.MapLeftKey("Guid"));

... 将生成一个不需要的 CustomerAttributes 表。

        modelBuilder.Entity<Organization>()
            .HasMany(o => o.Attributes)
            .WithOptional()
            .HasForeignKey(o => o.Guid);

...不会编译,因为

引用约束的 Dependent Role 中所有属性的类型必须与 Principal Role 中相应的属性类型相同。

应该如何建立关系?还是设计不合适?

编辑:成功!

在 Raphaël Althaus 的指导下,我已准备好接受 EF 的方式,并为每个实体使用单独的跟踪表,但他建议创建一个新类,Cust 和 Loca 实体将继承该类,这让我走上了正确的方向。

首先,我创建了一个“父”类,它也为我提供了重构存储在大多数实体上的一些审计数据的地方:

public class ParentEntity
{
    [Key]
    public Guid Guid { get; set; }

    public DateTime? CreatedOn { get; set; }
    public string CreatedBy { get; set; }
    public DateTime? ModifiedOn { get; set; }
    public string ModifiedBy { get; set; }

    [Timestamp]
    public byte[] Version { get; set; }

    public virtual ICollection<Attribute> Attributes { get; set; }
}

然后我继承了 Cust 和 Loca 实体的父类:

public class Customer : ParentEntity
{ 
    public int CustomerId { get; set; }
    public Guid Guid { get; set; }
}

public class Location : ParentEntity
{ 
    public int LocationId { get; set; }
    public Guid Guid { get; set; }
}

我还修改了 Attribute 类以支持新的 FK 字段 EntityGuid:

public class Attribute
{
    public int AttributeId { get; set; }
    public Guid EntityGuid { get; set; }
    public string Name { get; set; }
    public string Value { get; set; }
}

这给了我几乎所有我需要的东西,除了......它试图将每个实体存储在新的 ParentEntity 表中。要解决我使用的问题:

        modelBuilder.Entity<Customer>().ToTable("Customers");
        modelBuilder.Entity<Location>().ToTable("Locations");

最后是把这一切结合在一起的部分:

        modelBuilder.Entity<ParentEntity>()
            .HasMany(e => e.Attributes)
            .WithRequired()
            .HasForeignKey(e => e.EntityGuid);

我能说的唯一缺点是 ParentEntity 作为主键,它是一个 Guid。但是我保留了我的其他键,并计划将它们用作集群索引。

4

1 回答 1

0

您的混合对象世界和 rDBMS 世界。

你在 ORM 中,所以你不应该介意(好吧,不完全,但在这种情况下,是的)你的数据库中到底有什么。

如果没有“链接”(关系)表,rDBMS 无法管理多对多关系(如何表示作为列表的外键?没有关系表是不可能的)。

在对象世界中,a List<x>iny和 a List<y>inx可以做到这一点,而无需任何“关系”实体。

编辑

如果您想要一个通用的“关系”表,您可以创建一个新实体(带有 Guid):客户和位置将从该新实体继承,属性实体将与该新实体链接。

于 2012-06-29T13:58:04.880 回答