是否可以做这样的事情:
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'需要初级 要定义的关键。
答案 0 :(得分:2)
这似乎是一个错误,因为如果您为{{1}提供keydown
,public
或internal
(但不是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属性使内部对包含上下文的程序集可见。