Dapper 不会因丢失数据而发出警告或失败

Posted

技术标签:

【中文标题】Dapper 不会因丢失数据而发出警告或失败【英文标题】:Dapper does not warn or fail with missing data 【发布时间】:2013-02-12 23:35:44 【问题描述】:

假设我有一个类(例如简单化),我想确保始终填充 PersonId 和 Name 字段。

public class Person

    int PersonId  get; set; 
    string Name  get; set; 
    string Address  get; set; 

目前,我的查询是:

Person p = conn.Query<Person>("SELECT * FROM People");

但是,我可能已经将我的数据库架构从 PersonId 更改为 PID,现在代码可以正常运行了。

我想做的是以下之一:

    用诸如Required的属性装饰PersonId属性(dapper可以验证)

    告诉 dapper 找出映射没有完全填写(即当类中的所有属性都没有被查询数据填写时抛出异常)。

目前这可能吗?如果不能,有人可以指出我如何在不严重影响性能的情况下做到这一点吗?

恕我直言,第二个选项是最好的,因为它不会破坏用户的现有代码,并且不需要对我们可能无法访问的类进行更多属性修饰。

【问题讨论】:

不是答案,但我更愿意使用“从人员中选择 PersonID、姓名、地址”而不是“选择 *”。当架构更改时,您的查询将失败。问题解决了。 @Dag 感谢您的评论,但不幸的是,Dapper 并非如此。我的模型可能有错误类型,例如 FullName 而不是 Name 在这种情况下根本没有例外。它只是假设您不想映射名称。如果我应该选择,对模式或模型不匹配的更改应该引发异常。有关更多信息,请参阅此要点(页面底部的 cmets):gist.github.com/aboutdev/4945917 【参考方案1】:

目前,不,这是不可能的。事实上,在很多情况下填充部分模型非常有用,所以我不想添加任何内容隐式。在许多情况下,域模型是数据模型的扩展视图,所以我认为选项 2 行不通 - 我知道它会在我的代码中出现无数个问题;p 如果我们将自己限制在更明确的选项...

到目前为止,我们故意避免使用属性之类的东西;我们的想法是尽可能保持简洁和直接。我并没有病态地反对属性——只是:不得不探测它们可能会有问题。但也许是时候了……我们也许还可以同时允许简单的列映射,即

[Map(Name = "Person Id", Required = true)]
int PersonId  get; set; 

NameRequired 都是可选的。想法?不过,这在某些方面存在问题 - 特别是目前我们只探测 我们可以看到的列,尤其是在可扩展性 API 中。

另一种可能性是我们检查的接口,允许您在加载后手动验证数据;例如:

public class Person : IMapCallback 
    void IMapCallback.BeforePopulate() 
    void IMapCallback.AfterPopulate() 
        if(PersonId == 0)
            throw new InvalidOperationException("PersonId not populated");
    

界面选项在很多方面让我更快乐:

它避免了很多额外的反射探测(只需要做一项检查) 更灵活 - 您可以选择对您来说重要的内容 它不会影响可扩展性 API

但是:它更手动。

我愿意提供意见,但我想确保我们得到它正确,而不是急于火上浇油。

【讨论】:

感谢您回答这个问号。为了回答您的观点,对于开发人员来说,该属性似乎比实现接口更容易。但是界面更干净,更一致。但是,潜在的问题仍然存在,即可以选择确保何时不映射数据模型。我可能不想对每条记录都进行回调,因为这会产生很多开销。我只是想确保我期望的列不会改变。这是我为测试所做的事情(警告:前方有龙)。我正在创建一个要点... 我创建了这个要点:gist.github.com/aboutdev/4945917 第 50 - 57 行是大部分更改。它不是任何形式的产品代码,而只是一个测试,看看它是否可能。我在这里验证的是返回给我的列可以由数据模型映射。因此,如果 fat-fingered-freddy 更改数据模型字段,代码将失败。或者如果他更改数据库字段,代码将失败。我希望这能澄清我想要做什么?这样,我们不会验证每一行,而只验证一次(更好?),所以它应该会快一点。 另一种方法是进行主开关以使事情像@AboutDev 建议的那样工作(如果没有抛出错误,则必须填充所有带有设置器的属性)。默认情况下,该开关可能会关闭。启用此开关并需要具有未填充属性的对象的开发人员将必须创建一个额外的类层,即 DB 对象层,它完全满足查询返回的列名。该层与可以为空的业务层不同。然后,开发人员会将 DB 对象映射到业务对象。

以上是关于Dapper 不会因丢失数据而发出警告或失败的主要内容,如果未能解决你的问题,请参考以下文章

Python 7Zip 错误因扫描警告而失败

通过 CSS 模块将 SCSS 变量导出到 JavaScript/Svelte,而不会发出 lint 警告

Vue CLI 3 - 构建不会因 lint 错误而失败

使用编译器指令在文件丢失时发出警告

为啥 pandas read_csv 会发出此警告? (元素比较失败)

在服务器 b.example.com 上配置 Apache 以允许从 example.com 请求 b.example.com 上的安全资源而不会发出警告?