【问题标题】:Dapper: is it possible to customize the type mapping of a specific field of a specific type?Dapper:是否可以自定义特定类型的特定字段的类型映射?
【发布时间】:2014-01-14 17:57:12
【问题描述】:

假设我有这个User 类:

public class User
{
    public int      ID          { get; set; }
    public string   FirstName   { get; set; }
    public string   LastName    { get; set; }
    public string   Email       { get; set; }
    public DateTime DateCreated { get; set; }
    public DateTime LastLogin   { get; set; }
}

我想映射到下表:

CREATE TABLE "user" (
  "ID"          int(11) NOT NULL AUTO_INCREMENT,
  "FirstName"   varchar(45) DEFAULT NULL,
  "LastName"    varchar(45) DEFAULT NULL,
  "Email"       varchar(255) NOT NULL,
  "DateCreated" int(11) NOT NULL,
  "LastLogin"   int(11) NOT NULL,
  PRIMARY KEY ("ID")
)

或者用更简单的话来说:我想将 DateTime 属性作为 int 字段存储在数据库中。但是,此类/表就是这种情况。其他类/表的映射可能不同。我正在考虑与类型或成员映射相结合的自定义转换函数。

是否可以使用 Dapper 实现这一点,如果可以,如何实现?

【问题讨论】:

    标签: c# sql dapper micro-orm


    【解决方案1】:

    底线是 Dapper 在设计上不支持此功能。其核心设计原则之一是表和对象之间的 1:1 映射,但列名到属性名的映射除外。

    我最终采用的解决方案是将 Dapper 与 AutoMapper 结合起来,无论如何我们已经在大量使用它。在我们的 Dapper DAO 中,在复杂的情况下,我们使用与域对象分离的实体对象并在它们之间进行映射。所以本质上域和表之间的非平凡映射变成了对象到对象映射的简单问题。

    【讨论】:

      【解决方案2】:

      现在应该可以使用自定义 SqlMapper.TypeHandler。请参阅单元测试中的 this 示例。 缺点是它将自定义类型处理应用于相同类型的所有字段。在您的情况下,所有 DateTime 属性都将通过类型处理程序进行评估。

      【讨论】:

        【解决方案3】:

        或许您可以使用新的SqlMapper.SetTypeMap 方法来实现这一点。请参阅https://stackoverflow.com/a/12615036/331281 了解更多信息。

        【讨论】:

        • 除非我记错了,SetTypeMap 可用于调整列映射到属性的方式,但不能调整类型转换的执行方式。
        【解决方案4】:

        据我所知,Dapper 目前不支持此类转换。您可以在 Dapper 中使用存储的 proc,并让 proc 为您进行转换。您还可以确保在将对象传递给 Dapper 之前完成数据/转换。

        我强烈质疑为什么您会选择 int 日期与 DateTime 但是在您的数据源中...似乎没有必要且过于复杂。

        “始终编写您的代码,就好像下一个维护它的人是一个知道您家庭地址的挥舞斧头的精神病患者一样。”

        【讨论】:

        • 这很重要 - 我希望这是这种类型的“正常”映射,用于查询它。我想使用 Dapper,因为我想依赖数据中的本机 SQL访问在应用程序级别控制的对象,而不是存储过程。我总是将日期时间映射到整数,除非我有充分的理由不这样做,因为众所周知,将日期时间对象映射到 MySQL 中的 sql 日期时间类型很容易出现时区不匹配错误。维护我的代码的人是一个知道我住在哪里的精神病患者。不过他没有斧头。
        • @AmirAbiri 无意冒犯,但 TimeZone 不匹配错误是程序员的错,而不是 ORM。将所有内容存储为 UTC 并计算显示的本地时间,您可以避免任何数据源中的问题。如果您不这样做的唯一原因是担心时区,请将您的 DateTimes 存储为 DateTimes。
        • 未采取 - 程序员错误是我试图避免的。作为架构师,任何设计的考虑之一是开发人员是否或多或少容易出错。我不是在责怪 ORM,我只是想以某种方式使用它。以 UTC 存储所有内容并对其进行精确控制正是我想要自定义转换函数的原因。无论如何,重点不是进行哲学辩论——我们可以同意不同意。问题是 Dapper 是否可以做到这一点?
        • 好吧,可能会影响您的对象...将您的 DateTime 自动属性更改为手动属性...在设置 DateTime 属性时,将值转换为 UTC。这保证了保存为 UTC 并读取为 UTC,无论程序员如何交互。然后您可以避免 int 转换并获得统一的数据表示。
        • 在这种情况下,我是挥舞斧头的精神病患者,虽然我已经清理了程序员本人的残骸,但我仍然需要处理一个伪劣数据库的残骸使用整数、字符串和其他可憎的方法来存储日期。有时你只需要处理垃圾。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多