1

我喜欢 Dapper、Massive、PetaPoco 等的“微”方法,我喜欢控制我们发送到数据库的 SQL,大多数时候它相对简单。我也喜欢使用 POCO,但是在处理有点灵活的架构设计时,您经常会遇到麻烦 :)

假设我们有一个 Person 实体,它总是具有以下属性。

  • ID
  • 姓名
  • 电子邮件
  • 电话

但在某些情况下,可能还有其他属性,例如

  • 特殊电话号码
  • 非常自定义值

我真的很想要一个具有我们知道将永远存在的共同属性的 POCO。但是让另一个可以在键/值集合中访问。

最好的方法是什么?是否有任何提到的“mirco-orm”支持这一点?我已经查看了所有内容,但没有发现任何迹象表明它们确实如此,但也许我错过了一些东西。

是否可以直接使用 SqlDataReader 执行此操作?还是在使用反射创建对象时读取数百行的性能会很差?提到的 orm 似乎都做得很好,我猜想在下面使用 DataReader。

希望你能帮忙:)

编辑:我可能应该提到我们无法控制应用程序架构。这是一个 ERP 解决方案,允许个人客户自定义他们的应用程序和底层数据库。在应用程序中添加字段会在数据库中添加列。坏我!因为一开始就没有说清楚

4

5 回答 5

1

Massive可以支持这一点,因为它将数据具体化为ExpandoObject的:

秘诀是 ExpandoObject。Massive 的所有输入和输出都是一个 Expando——它允许你用它做任何你想做的事情。在其核心,ExpandoObject 只是一个 IDictionary< string,object >

ExpandoObject 实现IDictionary<string, Object>and IEnumerable<KeyValuePair<string, Object>>,因此您可以以任何需要的方式枚举和测试成员。

Massive 的默认设置是发出SELECT *查询,因此 ExpandoObject 将包含表中的所有字段,即使是您不知道的字段。

您可以从 Github 获取 Massive 的当前代码

Dapper也可以选择动态对象,但与 Massive 不同的是,它只能选择数据,不能插入、更新或删除数据。编辑:查看 Dapper 文档,它似乎可以执行修改,因为它可以执行任何 sql。有一些关于使用 Dapper 执行插入的最新信息

于 2012-01-27T20:09:36.537 回答
0

在您的设计中使用每个类型继承的表或扩展表,以允许在实体上添加数据。

于 2012-01-27T19:18:05.360 回答
0

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”结果映射。

还支持选择字典并避免 N+1 选择。需要注意的是:我与 MyBatis 项目没有任何关系,我只是发现它非常灵活且非常可靠的数据映射器。我将它用于我的所有项目,主要是因为我编写了一个工具,只需将其指向数据库即可生成我的整个数据访问层。

设置它有点像 PITA,但也许它对你有用!

于 2012-01-27T19:32:48.103 回答
0

你可以看看 nHibernate 的动态映射。

http://ayende.com/blog/3942/nhibernate-mapping-dynamic-component

它允许您将此类扩展属性检索到 genericDirectory<string,object>中。因此,您的类具有此类通用包(字典)并动态扩展 XML 映射。

nHibernate 将为您完成剩下的工作。

于 2012-01-27T21:01:01.620 回答
-2

Id Name Email Phone 但在某些情况下可能会有其他属性,例如 SpecialPhoneNumber VeryCustomValue

将架构师送回程序员学校 101。设计错误 - Phone、SpecialPhoneNumber 都不是 Person 的属性(它不是 Person,而是“Entity”,因为它也可以是一个法律实体)。

它们是“联系点”或其他东西的列表。

也就是说,属性桶也可以在 ORM 中演示,但性能很差,但是嘿,这就是 sql 数据库的工作方式。属性桶的性能不佳。

于 2012-01-27T19:17:54.880 回答