【问题标题】:Are generic classes not supported as models in Entity Framework?实体框架中不支持泛型类作为模型吗?
【发布时间】:2014-02-26 02:57:11
【问题描述】:

我正在尝试做这样的事情:

public class TrackerContext : DbContext
{
    public bool TrackNewValues { get; set; }

    public TrackerContext(bool trackNewValues = false)
        : base()
    {
        TrackNewValues = trackNewValues;
    }

    public TrackerContext(string connectinString, bool trackNewValues = false)
        : base(connectinString)
    {
        TrackNewValues = trackNewValues;
    }

    public DbSet<AuditLog<string>> AuditLog { get; set; }
    public DbSet<AuditLogChild> LogChildren { get; set; }
}



public class AuditLog<UserIdOrUserNameColumnType>
{
    public AuditLog()
    {
        Children = new List<AuditLogChild>();
    }

    [Key]
    public Guid AuditLogID { get; set; }

    public UserIdOrUserNameColumnType UserId { get; set; }

    [Required]
    public DateTimeOffset EventDateUTC { get; set; }
}

但我猜DbSet&lt;AuditLog&lt;string&gt;&gt; 不受支持。我收到此错误:

附加信息:未映射类型“TrackerEnabledDbContext.AuditLog`1[System.String]”。 使用 Ignore 方法或 NotMappedAttribute 数据注释检查该类型是否被显式排除。 验证该类型是否被定义为一个类,不是原始的或泛型的,并且不是从 EntityObject 继承的。

有什么方法可以实现public DbSet&lt;AuditLog&lt;string&gt;&gt; AuditLog { get; set; } ?

【问题讨论】:

    标签: c# asp.net database entity-framework orm


    【解决方案1】:

    您无法映射泛型类型,因为实体框架根本不支持泛型实体类型。 使用 EF 代码优先方法时,您需要记住,您应该在允许实体框架创建 POCO proxies 的约束范围内对 POCO classes 建模。

    这意味着,简而言之,这样一个类:

    • 不应包含任何属性
    • 不应该是通用的
    • 应该公开
    • 不得密封
    • 不能是抽象的
    • 必须有一个没有参数的公共或受保护的构造函数

    【讨论】:

    • 你知道你的答案是正确的。但我真的很失望。因为它是可以完成的,只是没有在实体框架中实现。
    • @BilalFazlani:当你完成了它,我们就知道它可以完成了。
    • 非常有趣。我会试试看:)
    • 我认为这也是完全可行的。
    • @BilalFazlani 当并非所有数据类型都可映射时(无需序列化为 XML/JSON 等),您将如何完成任何类型的属性(从通用参数)到关系数据库列的映射。 )?
    【解决方案2】:

    我一直在实体框架中成功使用泛型类。 如果您按照以下方式声明您的类和 DbSet,它将起作用。

    public class AuditLogString : AuditLog<String>{}
    
    public DbSet<AuditLogString>  AuditLogStrings { get;set;}
    

    [更新] 我最近没有使用过这种方法,鉴于这个答案中的 cmets,我建议改用 Pawel 的答案。 但是我没有删除这个答案,因为我能够使用该方法。

    【讨论】:

    • 这对于您实际可以做的事情非常有限。例如,这种方法不适用于一对多关系中的导航属性。
    • @kirsteng @kjbartel 您可以使用导航属性,但这意味着您需要在另一边以及关系的后代中传播通用子类。 IE,如果AuditLogString 包含一个 FK 到另一个表(使用 TPH)并且还有多个派生类,那么你不能从基类映射它 - 它必须为每个孩子专门映射。
    • 这行不通。它很快变得复杂,在导航属性之间进行约束时我遇到了循环依赖
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-09
    • 2022-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-15
    相关资源
    最近更新 更多