实体框架核心:永远不会调用属性设置器(违反封装?)

时间:2017-11-19 22:27:33

标签: c# entity-framework-6 entity-framework-core

在EF Core和EF6中,调用属性的getter' Date' (见下文)给出正确的值,但请注意两者之间的细微差别:在EF Core中,永远不会调用setter!

这是我的模特:

public class MyModel
{      
    private DateTime _Date;
    private bool dateTimeHasBeenSet = false;
    public DateTime Date
    {
        get
        {
            return _Date;
        }
        set
        {
            dateTimeHasBeenSet = true;
            _Date = value;
        }
    }
}

这是我检索单个项目的方法:

        //Entity Framework 6
        using (Ef6Context context = new Ef6Context())
        {

            var m =  context.MyModels.First();

            // m.dateTimeHasBeenSet is true

        }

        //Entity Framework Core
        using (EfCoreContext context = new EfCoreContext())
        {

            var m = context.MyModels.First();
            // m.dateTimeHasBeenSet is false
        }

EF核心是否初始化备份字段而不是属性(通过反射)?这不违反封装吗?

我将一些代码从EF6迁移到EF Core,我真的希望避免浪费时间手动调用每个setter背后的逻辑...

编辑:如果我将备份字段从_Property重命名为_PropertyX(在本例中,它将是_DateX),我会尝试将我的备份字段重命名为我的setter EF核心!

1 个答案:

答案 0 :(得分:3)

使用EF Core我们有一个Backing Fields的概念:

  

支持字段允许EF读取和/或写入字段而不是属性。

当EF根据惯例发现您的属性存在备用字段时,它将在实体化时使用该字段而不是您的属性。只有在您的实体具体化后,如果EF需要更新您的实体,它将尽可能使用该属性(当该属性不是只读时),否则它将继续使用您的支持字段。

你可以告诉,EF Core在通过以下代码实现实体时总是使用你的属性(只能使用Fluent API):

modelBuilder.Entity<MyModel>()
    .Property(b => b.Date)
    .HasField("_Date")
    .UsePropertyAccessMode(PropertyAccessMode.Property);

要了解有关支持字段的详情,请转到here

如果您要将此配置应用于模型中的所有属性,可以使用UsePropertyAccessMode的{​​{1}}实例方法,如下所示:

ModelBuilder