C# 使EF Core 2使用仅getter属性而不使用backing字段
我的目标是使Entity Framework 2能够很好地使用以下代码:C# 使EF Core 2使用仅getter属性而不使用backing字段,c#,entity-framework,.net-core,entity-framework-core,C#,Entity Framework,.net Core,Entity Framework Core,我的目标是使Entity Framework 2能够很好地使用以下代码: public class Foo { public Guid Id { get; } // This should NOT change public string NotRequiredProperty {get; set;} public Foo(Guid id) => Id = id; private Foo() { } // Empty constructor is ne
public class Foo
{
public Guid Id { get; } // This should NOT change
public string NotRequiredProperty {get; set;}
public Foo(Guid id) => Id = id;
private Foo() { } // Empty constructor is necessary for EF Core I believe?
}
我读过一篇文章,上面说可以做到以下几点:
// Class
private Guid _id;
public Guid Id => _id;
// Configuration
modelBuilder.Entity<Foo>()
.Property(b => b.Id)
.UsePropertyAccessMode(PropertyAccessMode.FieldDuringConstruction);
//类
私有Guid _id;
公共Guid Id=>\u Id;
//配置
modelBuilder.Entity()
.Property(b=>b.Id)
.UsePropertyAccessMode(PropertyAccessMode.FieldinConstruction);
这可能有用
我在这里看到的唯一改进是,我需要显式声明私有支持字段,即使{get;}
意味着隐式创建了一个
如何使EF Core只需一个
{get;}
(当然还有一些必需的实体配置)EF Core 2.1引入的功能通常可以满足您的要求。您不再需要空构造函数了-EF Core将能够使用带有Guid id
参数的构造函数
但是,有两个限制适用于Id
属性。首先,它是一个只读属性(因此由只读
字段支持,该字段只能从构造函数设置)。在显式支持字段示例中,如果将其定义为private readonly Guid\u id代码>。那么示例配置将无法工作
文件部分说明:
一旦通过构造函数设置了属性,就可以将其中一些属性设置为只读。EF Core支持这一点,但需要注意以下几点:
- 没有设置器的属性不按约定映射。(这样做往往会映射不应映射的属性,例如计算属性。)
- 使用自动生成的键值需要读写的键属性,因为插入新实体时需要由键生成器设置键值
注意第二颗子弹,因为这是第二个问题。按约定的Id
属性是PK,自动生成Guid
和按约定的数字类型PKs
因此,您需要在两个选项中进行选择-通过添加私有集,使Id
非只读代码>如链接中所建议,或(这是问题“如何使EF Core仅使用{get;}
”)的答案)使用以下流畅配置使其非自动生成:
modelBuilder.Entity<Foo>()
.Property(e => e.Id)
.ValueGeneratedNever();
modelBuilder.Entity()
.Property(e=>e.Id)
.ValueGeneratedNever();
谢谢您的回答。从技术上讲,添加私有集
并不能回答我的问题,因为我只想使用`{get;};我的构造函数应该只能更改它。所以你说,如果我用ValueGeneratedNever()
配置Id`,只要我在构造函数中传递GUID
,我的示例就会完全按照我想要的方式工作?@S.tenBrinke确实,这就是确切问题的答案。是的,您应该将新实体的现有Guid
或Guid.NewGuid()
传递给实体构造函数。这基本上与EF无关-这是只读字段的C#(CLR)要求-它们只能在类构造函数中设置不带readonly
修饰符的code>字段相当于具有私有setter,因为支持字段可以从类内的任何位置或通过反射进行设置。正如我在回答中提到的,如果您将字段标记为readonly
,您将遇到与隐式get
only属性相同的问题,并且将被迫使用相同的解决方案ValueGeneratedNever
,并仅通过构造函数传递Id
值。