【问题标题】:Entity framework Core : property setter is never called (Violation of encapsulation?)实体框架核心:永远不会调用属性设置器(违反封装?)
【发布时间】:2017-11-19 22:27:33
【问题描述】:

在 EF Core 和 EF6 中,调用属性“Date”(见下文)的 getter 会给出正确的值,但请注意两者之间的细微差别:在 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 被调用英孚核心!

【问题讨论】:

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


    【解决方案1】:

    对于 EF Core,我们有一个支持字段的概念:

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

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

    您可以通过执行以下代码(仅适用于 Fluent API)来判断 EF Core 在具体化您的实体时始终使用您的属性:

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

    要了解有关支持字段的更多信息,请转到here

    如果您想将此配置应用于模型中的所有属性,您可以使用ModelBuilderUsePropertyAccessMode 实例方法,如下所示:

    modelBuilder.UsePropertyAccessMode(PropertyAccessMode.Property);
    

    【讨论】:

    • 感谢您解释该行为以及如何禁用它,有没有办法全局禁用它?我正在迁移 80 个表 * 20 列,这甚至不是我的代码...
    • @Akli 我更新了关于如何在整个模型中全局应用它的答案:)
    猜你喜欢
    • 2020-04-18
    • 2018-07-22
    • 1970-01-01
    • 2022-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-23
    • 2019-02-19
    相关资源
    最近更新 更多