在运行时修改实体框架模型

时间:2010-10-26 00:39:23

标签: .net entity-framework c#-4.0 entity-framework-4

这纯粹是与EF4相关的概念和设计理念。

示例/场景是一个大型ERP或CRM类型系统,公司可能需要添加传统的“用户定义字段”来捕获其他数据。

我知道EF有一些功能可以在运行时将模型推送到数据库,但问题是你能否使用EF来修改模型并实时更新数据存储?

换句话说,如果我为用户提供添加用户定义列的机制,那么关联数据类型和空值要求可以通过EF动态完成,然后记住以后的所有会话吗?

它在那里,但我想你们都会看到我所得到的。

布伦特

5 个答案:

答案 0 :(得分:14)

我过去曾几次被问过这个问题。没有明显或简单的方法。可能没有办法,但我们是开发人员,总有办法!我知道那是什么吗?不,我可以想出一些想法吗? ....嗯..在运行时,该模型基于元数据空间中的强类型类。您可以动态创建它们。但是你需要修改edmx文件的xml。那里有LINQ to XML或xpath。修改数据库模式...模型如何首先构建dbs ...它创建sql然后执行它。你必须创建sql(如何?耸肩)和执行它(objectcontext.executestorecommand())。可行?可能?我没有线索。真的答案是否定的......据我所知,VS或.NET 4(EF API)中没有任何内容可以轻松实现这一点。当然有人比我花了更多的聪明和耐心(浪费了?)很多时间(试图)超过EF来取消它。然而,基于你对Jeremy的博客帖子的回应,你正在寻找内置/方便的东西。用“不”来回答更容易。

朱莉

答案 1 :(得分:11)

解决问题的方法通常不止一种,这也不例外。在这种情况下,您正在寻找的是允许用户向您的应用和数据库添加新字段,并在您的应用中使用这些字段。一些方法是:

a)允许用户修改数据库架构 b)创建一个单独的结构来定义“用户定义的字段”并将数据存储在其中 c)在表中创建可为空的“保留”字段,用户更可能需要自己的字段。

在应用程序中需要用户定义的自定义字段时,我更喜欢(b)方法,有时候更喜欢(c)方法。以下是三者中每一个的优点/缺点:

修改架构

Risky :如果您允许用户修改数据库架构,您在哪里绘制线?如果他们可以添加字段,他们也可能会更改现有字段的定义,添加或删除索引等。这可能会导致支持噩梦,包括由用户执行的架构修改触发的错误,性能问题等。
Performant :在现有表中内嵌存储新的用户定义字段通常比单独的结构具有性能优势,但只要它们不会随着更改而过度使用。 • Clunky :EF在设计时确定模式,因此要在运行时使其工作,您需要在运行时使用表示新字段的成员生成新的实体类,并且您需要更新在运行时映射元数据。运行时生成的实体类可以从设计时生成的类继承,因此您只需要为新的用户定义字段添加成员和映射。虽然可能,但它很笨重。使用运行时生成的类的代码需要使用反射来访问在运行时创建的新成员。

单独的结构

用户友好型:通过创建用于存储自定义字段的单独结构,您可以为用户构建应用程序逻辑,以添加/删除这些字段等。他们不需要乱用数据库相反,您可以在应用程序中添加维护表单以添加新字段 • EF-friendly:无需在运行时混淆实体类和映射元数据。一切都是在设计时定义的,用户定义的字段只是数据 •性能稍差:由于额外的往返或其他连接,使用单独的表来定义和存储用户定义的字段可能会使查找成本更高。

Separate table structure for user defined fields

保留字段

通常足够:在许多情况下,自定义字段仅用于一个或多个额外字段。保留几列通常可以满足99%的用户需求。在LOB应用程序中,即使每个表中的通用“备注”字段也足够了 •受限制:如果用户需要的字段多于您保留的字段数,或者您保留的其他数据类型,那么这可能是一个限制。
Performant:内联列,无需额外往返或连接即可检索 •在设计时定义:没有运行时弄乱实体类型定义或映射。

Reserved fields

答案 2 :(得分:2)

布伦特今天在推特上发帖(在这篇文章后差不多2年),看看是否有任何变化。 EF仍然不支持此方案。然而,Rowan Miller有一篇关于如何使用Code First http://romiller.com/2012/03/26/dynamically-building-a-model-with-code-first/

解决这个问题的有趣帖子

这可能会或可能不会做你需要的,但值得一看。

答案 3 :(得分:1)

Jeremy Miller在this article中讨论了类似的设置。他正在使用nHibernate,但它可能会给你一些想法。

答案 4 :(得分:0)

这是我过去使用的@KristoferA答案的Reserved fields版本。

您可以在每个表上添加一个额外的XML(或JSON)列,这些列可能需要自定义数据,然后使用EF从db读取/写入。在读取反序列化XML(JSON)并将其传递给应该处理映射的机制之后,然后将其呈现给用户。写入从UI读取的数据也是如此 - >映射到对象 - >序列化为XML(JSON) - >并写入这些额外的字段。