实体框架中是否不支持通用类作为模型?

Bil*_*ani 9 c# database asp.net orm entity-framework

我想做这样的事情:

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; }
}
Run Code Online (Sandbox Code Playgroud)

但我猜DbSet<AuditLog<string>>不支持.我收到此错误:

附加信息:未映射类型'TrackerEnabledDbContext.AuditLog`1 [System.String]'.使用Ignore方法或NotMappedAttribute数据批注检查未明确排除类型.验证类型是否已定义为类,不是原始类型还是通用类型,并且不从EntityObject继承.

我有什么方法可以实现public DbSet<AuditLog<string>> AuditLog { get; set; }吗?

Paw*_*ger 9

您无法映射泛型类型,因为实体框架根本不支持通用实体类型.使用EF Code-First方法时,您需要记住,您应该在允许Entity Framework创建POCO代理的约束内对POCO类进行建模.

这意味着,很快就会说出这样一个类:

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

  • @BilalFazlani:当你完成它之后,我们就会知道它可以完成. (3认同)

Kir*_*eed 8

我一直在Entity Framework中成功使用泛型类.如果以下列方式声明您的类和DbSet,它将起作用.

public class AuditLogString : AuditLog<String>{}

public DbSet<AuditLogString>  AuditLogStrings { get;set;}
Run Code Online (Sandbox Code Playgroud)

[更新]我最近没有使用过这种方法,根据对这个答案的评论,我建议Pawel的回答.但是我没有删除这个答案,因为我能够使用该方法.

  • 您实际可以做的事情非常有限.例如,这种方法不适用于一对多关系中的导航属性. (2认同)
  • @kirsteng @kjbartel 您可以使用导航属性,但这意味着您需要在另一侧以及关系的后代中传播通用子类。即,如果 `AuditLogString` 包含到另一个表(使用 TPH)的 FK 并且也有多个派生类,那么您无法从基类映射它 - 必须为每个子项专门映射它。 (2认同)