我将实体框架用于一个相当简单的问题跟踪应用程序。 我想通过添加其他属性(例如:
)为用户提供扩展“问题”实体的功能我想到了完成任务的两种方法:
可扩展数据库方法
这种做法只是一个想法,我不知道如何使用实体框架实现,所以我非常希望得到你的帮助。 这是基本概念:
现在我只是不知道如何实现第3步,因为使用实体框架并且存在从表中生成的EF实体对象(DB优先),因此每个新列理论上都必须重新映射和重新编译DAL项目。
你还有其他建议吗?
字典方法
这种方法我知道如何实现
但它有许多缺点(如果你看到如何过来请发布)。
答案 0 :(得分:3)
我知道这个问题很老了,但是没有什么能阻止你在运行时使用你特定时刻的数据库模式来构建你的EF数据模型。由于您的大多数数据模型都是静态的,因此增加的复杂性本地化为在运行时可以更改的实体:
在运行时向数据库添加列时,还需要向相应类型添加属性。这意味着您的类型是在运行时构造的。您可能会在运行时使用其他属性创建派生的类型(或实现某些接口),以便您的编译时代码具有合理的类型来处理。这可以使用Reflection.Emit完成。
每当架构发生变化时,您都需要在运行时动态构建EF映射。您可以使用EF Code First执行此操作。如果您的映射符合正常的EF Code First约定,那么除了确保将运行时类型添加到映射之外,您无需执行此操作。否则,您必须实现在运行时为其他属性确定和配置必要映射的代码。
任何利用其他属性的查询都需要在运行时动态构建。这意味着要在LINQ查询中使用building member access expressions。同样,访问仅在运行时已知的其他属性的值需要reflection。
你是正确的,要警惕你的第二种方法,这种方法更广为人知的是Entity-Attribute-Value (EAV) data modeling。这种方法有许多缺点,其中最重要的是增加了连接/查询复杂性和缺少外键支持。但是,由于EAV模型是在编译时声明的,因此可以说更容易实现。
或者,您可以考虑专门为具有灵活架构的实体使用其他数据存储,例如document databases。
答案 1 :(得分:0)
因此理论上每个新专栏都必须重新映射并重新编译DAL项目。
你回答了自己的问题:) EF使用固定数据库模式,因此无论如何第一个选项都不是一个选项。