简体   繁体   English

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

[英]EF Core base entity class inheritance and readonly properties

Is it possible to do something like this: 是否可以做这样的事情:

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;
}

This is base class, all entities should inherit from this class. 这是基类,所有实体都应从此类继承。 Also this properties should be readonly (I'm using backing properties ), because EF need to take care of them. 另外,此属性应该是只读的(我正在使用backing属性 ),因为EF需要照顾它们。

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

    public string Description { get; set; }
}

And OnModelCreating is empty. 并且OnModelCreating为空。 When I run migrations, I get message : 运行迁移时,我收到消息:

'The entity type 'Project.Database.Models.Category' requires a primary key to be defined. '实体类型'Project.Database.Models.Category'需要定义主键。

This seems to be a bug, because it works if you provide public , internal or protected (but not private or none) setter for the Id property, or if you specify the key of the derived entity explicitly via Fluent API 这似乎是一个错误,因为如果您为Id属性提供publicinternalprotected (但不是private或没有)setter,或者如果您通过Fluent API显式指定了派生实体的键,那么它将起作用

modelBuilder.Entity<Category>().HasKey(e => e.Id);

which of course defeats the whole purpose of using the base class property. 当然,这违背了使用基类属性的全部目的。

You might consider reporting it to EF Core GitHub . 您可以考虑将其报告给EF Core GitHub

The problem is that your BaseEntity.Id property is read only. 问题是您的BaseEntity.Id属性是只读的。

Your Id property is implemented as an expression-bodied member (the => syntax), which is merely syntactic sugar for a get-only property. 您的Id属性被实现为表达式主体成员 (=>语法),这仅仅是get-only属性的语法糖。

So, your code: 因此,您的代码:

public Guid Id => _id;

is equivalent to: 等效于:

public Guid Id { get { return _id; } }

EF must be able to set the values of mapped properties. EF必须能够设置映射属性的值。 You'll have to use traditional syntax to implement the property, and you'll have to provide a setter. 您将必须使用传统语法来实现该属性,并且必须提供一个setter。 If your context is in the same assembly as your model, you could mark the setter as internal so that the property is read only outside the assembly. 如果上下文与模型位于同一程序集中,则可以将setter标记为内部,以便该属性仅在程序集外部读取。 If your context is in a different assembly, you could still mark the setter as internal, then use the InternalsVisibleTo attribute to make internals visible to the assembly containing your context. 如果上下文在其他程序集中,则仍可以将setter标记为内部,然后使用InternalsVisibleTo属性使内部对包含上下文的程序集可见。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM