EF Core基础实体类继承和只读属性

时间:2016-10-09 13:32:28

标签: c# entity-framework asp.net-core entity-framework-core .net-core

是否可以做这样的事情:

public abstract class BaseEntity : IEntity
{
    private Guid _id;
    private DateTime _createdOn;
    private DateTime _modifiedOn;
    private byte[] _timestamp;

    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id => _id;

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public DateTime CreatedOn => _createdOn;

    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DateTime ModifiedOn => _modifiedOn;

    [Timestamp]
    public byte[] Timestamp => _timestamp;
}

这是基类,所有实体都应该从这个类继承。此属性也应该只读(我使用backing properties),因为EF需要处理它们。

public class Category : BaseEntity
{
    [Required]
    public string Name { get; set; }

    public string Description { get; set; }
}

OnModelCreating为空。 当我运行迁移时,我收到消息:

  

'实体类型' Project.Database.Models.Category'需要初级   要定义的关键。

2 个答案:

答案 0 :(得分:2)

这似乎是一个错误,因为如果您为{{1}提供keydownpublicinternal(但不是protected或无)设置器,它就有效}或者,如果您通过Fluent API明确指定派生实体的键

private

这当然违背了使用基类属性的全部目的。

您可以考虑将其报告给EF Core GitHub

答案 1 :(得分:1)

问题是您的BaseEntity.Id属性是只读的。

您的Id属性是以expression-bodied member(=>语法)实现的,这只是get-only属性的语法糖。

所以,你的代码:

public Guid Id => _id;

相当于:

public Guid Id { get { return _id; } }

EF必须能够设置映射属性的值。您必须使用传统语法来实现该属性,并且您必须提供一个setter。如果您的上下文与模型位于同一个程序集中,则可以将setter标记为internal,以便该属性仅在程序集外部读取。如果您的上下文位于不同的程序集中,您仍然可以将setter标记为internal,然后使用InternalsVisibleTo属性使内部对包含上下文的程序集可见。