如何让EF Core 2支持仅含Getter的属性(无显式私有字段)
如何在EF Core 2中使用只读自动属性({ get; })而无需显式后备字段
你完全可以保留{ get; }这种只读自动属性的写法,不需要手动声明私有后备字段——EF Core 2能够识别C#编译器为自动属性生成的隐式后备字段,只需要在实体配置中做几处简单设置即可。
步骤1:保持实体类的原有写法
你的实体类不需要修改,继续使用只读自动属性和私有无参构造函数:
public class Foo { public Guid Id { get; } // 只读自动属性,编译器会自动生成私有后备字段 public string NotRequiredProperty { get; set; } // 供业务代码使用的公共构造函数,确保Id在创建时被初始化 public Foo(Guid id) => Id = id; // EF Core需要的私有无参构造函数(用于从数据库实例化实体) private Foo() { } }
步骤2:配置EF Core实体映射
在你的DbContext的OnModelCreating方法中,为Foo实体添加如下配置:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Foo>(entity => { // 显式指定Id为主键(EF通常会自动识别名为Id的属性,但显式声明更清晰) entity.HasKey(f => f.Id); // 关键配置:指定自动生成的后备字段,并设置构造期间的访问模式 entity.Property(f => f.Id) .HasField("<Id>k__BackingField") // C#编译器为Id属性生成的隐式后备字段名 .UsePropertyAccessMode(PropertyAccessMode.FieldDuringConstruction); }); }
为什么这样可行?
- C#编译器会为
{ get; }的只读自动属性生成一个命名为<PropertyName>k__BackingField的私有后备字段,我们通过HasField方法告诉EF Core这个字段的存在。 UsePropertyAccessMode(PropertyAccessMode.FieldDuringConstruction)的作用是:EF Core在通过私有无参构造函数创建实体实例时,直接访问后备字段来设置Id的值;而在业务代码中访问Id属性时,依然通过公共的getter,保证了Id的只读性(无法在构造后修改)。
补充说明
如果你担心编译器生成的字段名可能发生变化(虽然在稳定的C#版本中这个命名规则是固定的),目前在EF Core 2中没有更优雅的自动发现方式——因为自动属性的隐式字段名不符合EF默认的字段匹配规则(比如_id、_Id这类命名),所以必须显式指定HasField。
这样配置完成后,EF Core 2就能正常处理Foo实体的读写操作,同时保持Id属性在业务代码中的不可修改性。
内容的提问来源于stack exchange,提问作者S. ten Brinke
相关产品推荐
相关产品推荐

