【问题标题】:How to disable insert in Entity Framework?如何在实体框架中禁用插入?
【发布时间】:2012-06-11 06:48:56
【问题描述】:

有什么方法可以禁用实体框架中的实体插入?

我正在使用 DDD,并且在特定的有界上下文中,用户表的某些必需的数据库字段没有意义(在此上下文中)。所以,我想从 User 实体中删除它们,但这样做我失去了将 new 用户保存到数据库的能力。没关系,因为在这种情况下,我不应该创建用户。

我的第一个想法是禁用用户实体上的插入(但允许更新)。

可行吗?或者,这种情况有其他解决方案吗?

【问题讨论】:

  • 听起来你已经受到了那个例外的保护,不是吗?我发现投资这种“保护”是浪费时间。在我看来,“身份和访问管理”BC 应该为您提供必要的查询方法和表示。
  • 也许你是对的。但是,当工作量不大时,我总是更喜欢出现编译时错误而不是运行时错误。
  • 另外,假设另一个开发人员试图弄清楚为什么一个简单的插入会引发异常。他可能需要很长时间才能意识到真正的问题。
  • 沟通对我来说似乎很重要。但这不是重点。这里的问题是您正在(重新)使用 EF 来实现本质上应该是用户数据的只读视图。您允许人们首先访问他们不应该能够访问的 Object/DbContext。您缺少传达这一点的抽象级别。

标签: entity-framework domain-driven-design


【解决方案1】:

您无法禁用插入,但您可以查看是否有任何实体被标记为插入并在这种情况下触发异常。

进行此类处理的最佳位置是覆盖SaveChanges 方法:

public override int SaveChanges(SaveOptions options)
{
    if (ObjectStateManager.GetObjectStateEntries(EntityState.Added)
                          .Where(e => !e.IsRelationship)
                          .Select(e => e.Entity)
                          .OfType<User>()
                          .Any())
    {
        throw new InvalidOperationException("User cannot be inserted");
    }

    return base.SaveChanges(options);
}

这是运行时行为,但因为 EF 在修改操作之间没有区别(都在单个 SaveChanges 内),所以您无法在编译时检测到插入。

【讨论】:

  • 谢谢!如果有人尝试插入用户,至少我可以提供更有意义的错误。
  • 如果我可以扩展 DbSet 以创建 ReadOnlyDbSet 并覆盖 Add 方法会更好。但是 Entity Framework 背后的人决定让构造函数内部化:/
  • 这无济于事,因为还有其他方法可以插入用户而无需在集合上调用 Add
猜你喜欢
  • 1970-01-01
  • 2016-12-07
  • 1970-01-01
  • 1970-01-01
  • 2012-08-30
  • 1970-01-01
  • 1970-01-01
  • 2012-06-05
  • 2011-07-27
相关资源
最近更新 更多