如何在不使用继承的情况下在 Entity Framework 中重用 class?

How can you reuse a class in Entity Framework without using inheritance?

我有一堆简单的 类 被其他各种 类 引用。例如,

class Version {
    // PK is Major, Minor, Build, Revision
    int Major { get; set; }
    int Minor { get; set; }
    int Build { get; set; }
    int Revision { get; set; }
}

class DraftArticle {
    int Id { get; set; }
    string Title { get; set; }
    string Description { get; set; }
    ICollection<Version> AffectedVersions { get; set; }
}

class Article {
    int Id { get; set; }
    string Title { get; set; }
    string Description { get; set; }
    ICollection<Version> AffectedVersions { get; set; }
}

class DbContext : System.Data.Entity.DbContext {
    System.Data.Entity.DbSet<DraftArticle> DraftArticles { get; set; }
    System.Data.Entity.DbSet<Article> Articles { get; set; }
}

如上所示使用时,Entity Framework 将创建三个 tables -- [DraftArticles]、[Articles] 和 [Versions],其中 [Versions] table 将具有以下 extra 列 -- [Discriminator]、[DraftArticle_Id] 和 [Article_Id].

我的目标是将 DraftArticles 和 Articles 的版本记录分成单独的 tables。

我知道 可以 使用 inheritance and/or ComplexType 来完成,但我想避免这两种情况,因为它需要需要额外的 类.

例如下面的增改工作

// additions
class DraftArticleVersion : Version { }

class ArticleVersion : Version { }

// modifications
class DraftArticle {
    ...
    ICollection<DraftArticleVersion> AffectedVersions { get; set; }
}

class Article {
    ...
    ICollection<ArticleVersion> AffectedVersions { get; set; }
}

class DbContext : System.Data.Entity.DbContext {
    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        modelBuilder.Entity<DraftArticleVersion>().Map(m => {
            m.MapInheritedProperties();
            m.ToTable("DraftArticleAffectedVersions");
        });

        modelBuilder.Entity<DraftArticleVersion>().Map(m => {
            m.MapInheritedProperties();
            m.ToTable("ArticleAffectedVersions");
        });
    }

    ...
}

此外,当使用像 AutoMapper 这样的框架时,它需要额外的(重复的)映射定义。

理想情况下,我希望看到的是在 属性 级别 而不是 级别 Class 级别。例如,

class Version {
    // PK is Major, Minor, Build, Revision
    ...
}

class DraftArticle {
    ...
    ICollection<Version> AffectedVersions { get; set; }
}

class Article {
    ...
    ICollection<Version> AffectedVersions { get; set; }
}

class DbContext : System.Data.Entity.DbContext {
    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        // somehow apply .ToTable("DraftArticleAffectedVersions") to DraftArticle.AffectedVersions

        // somehow apply .ToTable("ArticleAffectedVersions") to Article.AffectedVersions
    }

    ...
}

有人知道这是否可以做到吗?您是否知道重用 类 而无需 创建额外 类 and/or 映射的任何其他方法?

正如评论所暗示的那样 - 你不会喜欢这个答案,即你正在尝试做一些没有多大意义的事情,所以 EntityFramework 不支持它.

通过说 Article 和 Draft 都有一个列表 "Versions",您已经告诉 EF 两者都指的是同一件事 - 因此只有一个 table。但是你说你想让他们指代不同的东西。为什么?

正如 Akash 所说,更好(更规范化)的设计将避免需要这种奇怪的结果。