ORM,用于具有半灵活模式设计的数据库
本文关键字:模式 数据库 用于 ORM | 更新日期: 2023-09-27 18:21:53
我喜欢Dapper、Massive、PetaPoco等的"微"方法,我喜欢控制我们发送到数据库的SQL,大多数时候它相对简单。我也喜欢使用POCO,但是当处理一个稍微灵活的模式设计时,你经常会遇到麻烦:)
假设我们有一个Person实体,它总是具有以下属性。
- Id
- 名称
- 电子邮件
- 电话
但在某些情况下,可能会有其他属性,如
- 特殊电话号码
- VeryCustomValue
我真的很想要一个POCO,它具有我们知道永远存在的共同特性。但要在键/值集合中访问另一个。
什么是最好的方法?提到的"mirco-orm"中有任何一个支持这一点吗?我看了他们所有人,但没有发现任何迹象表明他们有,但也许我错过了什么。
是否可以使用SqlDataReader直接执行此操作?或者在使用反射创建对象时,读取数百行的性能会很差吗?上面提到的orm似乎都做得很好,我想下面使用了DataReader。
希望你能帮忙:)
编辑:我可能应该提到,我们无法控制应用程序体系结构。这是一个ERP解决方案,允许单个客户自定义其应用程序和底层数据库。在应用程序中添加字段会在数据库中添加列。糟糕的我!由于一开始就没有明确这一点,
Massive可以支持这一点。因为它将数据具体化为ExpandoObject的:
秘密酱汁是ExpandoObject。所有进入和Massive的所有产品都是Expando,它允许您用它做任何你想做的事。在它的核心,ExpandoObject只是一个IDictionary<字符串,对象>
ExpandoObject实现了IDictionary<string, Object>
和IEnumerable<KeyValuePair<string, Object>>
,因此您可以以任何需要的方式枚举和测试成员
Massive的默认值是发出SELECT *
查询,因此ExpandoObject将包含表中的所有字段,即使是您不知道的字段。
您可以从Github获取Massive的当前代码。
Dapper也可以选择动态对象,但与Massive不同,它只能选择数据,不能插入、更新或删除数据。编辑:查看Dapper文档,它似乎可以执行修改,因为它可以执行任何sql。有一些关于使用Dapper执行插入的最新信息。
在设计中使用每类型继承表或扩展表,以允许在实体上添加数据。
MyBatis.NET(以前的iBatis.NET)是一个数据映射器工具,我觉得它有一个非常有用的功能。如果您从未听说过它,它是一个ORM工具,允许您编写SQL,创建域对象,并使用XML将数据库列映射到域对象属性。
其中一个结果映射可能看起来像:
<resultMap id="Contact" class="Contact" >
<result property="ContactId" column="ContactId" />
<result property="FirstName" column="FirstName" />
<result property="MiddleInitial" column="MiddleInitial" />
<result property="LastName" column="LastName" />
</resultMap>
在那里,您有一个结果的id、一个类别名(例如,映射到Namespace.Folder.Contact)和一个列到属性映射的列表。
您可能感兴趣的是,可以像继承类一样扩展结果映射。在你的情况下,你可能有:
<resultMap id="Person" class="Person" >
<result property="Id" column="Id" />
<result property="Name" column="Name" />
<result property="Email" column="Email" />
<result property="Phone" column="Phone" />
</resultMap>
对于您的其他情况:
<resultMap id="PersonExtended" extends="Person" class="Person">
<!-- inherits all the "Person" result map properties -->
<result property="SpecialPhoneNumber" column="SpecialPhoneNumber" />
<result property="VeryCustomValue" column="VeryCustomValue" />
</resultMap>
然后您将有两个独立的查询,一个只选择基本信息并映射到"Person"结果映射,另一个查询映射到包含更多列的"PersonExtended"结果映射。
还支持选择Dictionaries和避免N+1选择。需要注意的是:我与MyBatis项目没有任何关系,我只是发现它非常灵活,是一个非常可靠的数据映射器。我在所有项目中都使用它,主要是因为我编写了一个工具,只需将其指向数据库,就可以生成我的整个数据访问层。
设置它有点像PITA,但也许它对你有用!
您可以查看nHibernate的动态映射。
http://ayende.com/blog/3942/nhibernate-mapping-dynamic-component
它允许您将此类扩展属性检索到通用Directory<string,object>
中。因此,您的类具有这样的通用包(字典),并动态扩展XML映射。
nHibernate会帮你完成剩下的工作。
Id名称电子邮件电话但在某些情况下,可能会有其他属性,如特殊电话号码VeryCustomValue
把架构师送回程序员学校101。设计错误-Phone和SpecialPhoneNumber都不是Person的属性(无论如何,Person不是Person,而是"实体",因为它也可以是法律实体)。
它们是一个"联系人"或其他什么的列表。
也就是说,属性桶也可以在ORM中演示,性能很差,但嘿,这就是sql数据库的工作方式。属性存储桶的性能不佳。