1

关于这个主题(在运行时修改实体框架模型)进行了相当多的讨论,但到目前为止,我还没有找到一个很好的解决方案。我们目前有一个使用 EF 4.0 构建的模型,需要允许客户将自定义字段添加到各种表中。我们目前已经使用一些描述新属性的通用表解决了这个问题,但我们发现该解决方案的性能不佳。

有谁知道动态向数据库添加列并更新 ORM 以在运行时反映这一点的好方法?

4

1 回答 1

2

在运行时更新 EF 以反映数据库中的更改没有好的、好的或可管理的方法。如果您确实有一个必须在运行时更改的数据库,那么 EF 对您来说不是一个好工具。EF 是强类型的 - 对数据库的每次更改不仅必须反映在映射中,而且还必须反映在用于加载和持久化数据的实体类中。

在运行时更改实体类总是进入运行时发出 IL 代码的区域。如果您通过使用动态模块和动态实体类型创建动态装配的过程,您将面临许多新挑战:

  • 您不会更改现有类型 - 每次用户添加或删除某些属性时,您都会生成一个新类型。
  • 新的类型生成为重建上下文的元数据工作空间带来了新的性能成本。如果您在服务器上使用它,您还必须确保它正确同步。另一个问题是旧类型的所有现有实例(在添加或删除属性之前)现在对于 EF 上下文的新实例是未知的,并且无法持久化。如果您还想保留它们,您还需要带有旧元数据工作区的 EF 上下文实例。
  • 你的很多代码可能会使用dynamic而不是真正的类型 = 没有编译时检查。直接与 EF 交互时,继承和接口将无用,因为必须映射继承(您不想要它)并且 EF 不接受接口。
  • 新类型在设计时是未知的 - 您不能将它用于设计时代码和编译。
  • EF 不喜欢dynamic或者ExpandoObject因为它使用反射进行映射 -> 在运行时您的动态实例必须是正确的类型,否则反射将不起作用。
  • 如何编写动态类型的查询?查询总是从通用实例开始DbSetObjectSet为具体类型创建 - 您也必须能够动态地创建这些实例。泛型参数必须是映射到当前上下文的类型 -dynamic在这种情况下无济于事,因为它不是映射类型。
  • .NET 在这种情况下有一个很好的行为。它无法卸载程序集。因此,每次生成新类型时,也会加载旧时间。

您还想在运行时更改 EF 吗?您当前的方法是正确的。只需对其进行调整以获得更好的性能,但请注意,这些要求总是伴随着性能成本——尤其是 EF。

或者使用链接表中提到的最后一种方法 - 直接在主实体中固定数量的预定义自定义字段。

于 2012-07-02T13:30:37.800 回答