最近我开始研究Dapper.我正在测试它,并能够做基本的CRUD,我的意思是基本的是工作在一个类与这个结构:
public class Product {
    public int Id {get;set;}
    public string Name {get;set;}
}

现在我正在寻找一些可以更容易地进行插入和更新并发现Dapper.Rainbow的东西.我检查了它,并能够使用它来获取和插入对象,如上所述.我的问题是,当产品具有导航属性时,我不能在该字段上插入.所以如果我有这个:

public class Product {
    public int Id {get;set;}
    public string Name {get;set;}
    public ProductCategory Category {get;set;}
}

我将无法做到这一点:

// connection is a valid and opened connection            
 var db = TestDatabase.Init(connection,300);
 var newId = db.Products.Insert(newProduct);

因为这个原因:

The member Category of type ProductCategory  cannot be used as a parameter value

如果我用类型int(数据库中相同的数据类型)替换类别,则可以解决问题.但是,如果我这样做,我将无法使用其类别信息查询产品,而不仅仅是(category)Id.

所以没有诉诸原始的Dapper,我如何使用导航属性的类进行插入和更新?我希望我可以执行以下操作,并告诉Dapper.Rainbow在插入或更新时忽略类别.

public class Product {
    public int Id {get;set;}
    public string Name {get;set;}
    public ProductCategory Category {get;set;}
    public int CategoryId {get;set;} // this will be the same field name in the database
}

这个场景是可以使用NHibernate,我可以有一个代理对象的类别并将其分配给产品并保存,并且映射工作完美.但是我很想使用Dapper,这就是为什么我正在探索,想要学习如何做这样的事情.

解决方法

不用Dapper.Rainbow

这是不可能的Dapper.Rainbow在其当前的形式,但my pull request in github使这成为可能.

我很惊讶,没有人建议使用Dapper.Contrib.我知道我问Rainbow是否有功能.但是我没想到没有人会注意到这个声明(特别是粗体字):

Now I was looking for something that would make it easier to do
inserts and updates
and found Dapper.Rainbow. I checked it out and was
able to use it to get and insert objects as described above. My
problem is that when Product has a navigation property I can’t do an
insert on that field
.

…并提出一个替代方案,一个已经在Dapper库中的解决方案.我想我应该更清楚我的问题,并明确询问一个解决方案是否存在于整个Dapper library that is in github的某个地方.所以在更多的挖掘图书馆后,我发现有一个支持我的问题.

Dapper.Contrib的路径

所有这些都与我的项目和彩虹工作良好,直到我需要更多的工作.我有一些表中有很多字段.如果我只是给Rainbow我的对象,那么它将对所有的字段进行更新,这不是很好.但是,这并不意味着我很快就跳出船,回到NH.所以在我实现自己的变更跟踪之前,我不想重新发明,特别是如果有人已经做了一个很好的工作,我已经在7月2日上网了.这个线程证实了我的知识,Rainbow不支持更改跟踪,但是另一个野兽,它被称为Dapper.Contrib.所以我开始尝试了.

所以我们再见面

The member Category of type ProductCategory cannot be used as a
parameter value

我和彩虹有同样的问题. Contrib不支持导航属性!我开始感觉到我正在用Dapper浪费我的时间,而且我所追求的表现只会是一厢情愿.直到…

WriteAttribute来到救援…

该类生活在Dapper.Contrib项目中包含的sqlMapperExtensions.cs文件中.我没有找到关于这个课程的任何文件,也没有任何意见可以很容易找到,并且对我说话,并说嘿,我是你正在寻找的.当我按照上面所述放置彩虹时,我偶然发现.

这个类的用法和我用IgnorePropertyAttribute一样,它是一个属性,你可以用它来装饰你的类的属性.您应该使用此属性来装饰任何不需要包含在Dapper创建的sql中的属性.所以在我的例子中,我告诉Dapper排除我需要做的类别字段:

public class Product {
    public int Id {get;set;}

    public string Name {get;set;}

    [Write(false)] // tell Dapper to exclude this field from the sql
    public ProductCategory Category {get;set;}

    public int CategoryId {get;set;}
}

我快到了

记住,我去Contrib的原因是因为更改跟踪功能. This SO thread,我上面提到的相同的链接指出,要进行更改跟踪,您需要为您的课程提供一个界面,并与Contrib一起使用.所以对于我的示例类,我需要有:

public interface IProduct {
    int Id {get;set;}
    string Name {get;set;}
    ProductCategory Category {get;set;}
    int Category {get;set;}
}

// and implement it on my Product class
public class Product : IProduct {
    public int Id {get;set;}

    public string Name {get;set;}

    [Write(false)]
    public ProductCategory Category {get;set;}

    int Category {get;set;}
}

我以为是,几乎!你可能会问我为什么需要在我的界面中定义类别,如果Dapper根本不关心它.其实这只会造成一个问题,我会解决的问题.

在我的具体情况下,有时我需要在“类别”字段上工作,同时保留“产品”对象的更改跟踪.为了保持跟踪功能,应该使用如下所示的接口类型来提供get call:

var product = connection.Get<IProduct>(id);

并且通过该调用,如果我不在界面中定义它,我将无法访问类别字段.但是如果我在我的界面中定义它,那么我会得到一个熟悉的错误

The member {member} of type {type} cannot be used as a parameter
value.

真的呢请停止.

判决

不需要担心,通过装饰接口成员,就像我们为该类做的一样,这个容易解决.所以使一切工作的最终配置应该是:

public interface IProduct {
    // I will not discuss here what this attribute does
    // as this is documented already in the github source.
    // Just take note that this is needed,// both here and in the implementing class.
    [Key]
    int Id {get;set;}

    string Name {get;set;}

    [Write(false)]
    ProductCategory Category {get;set;}

    int Category {get;set;}
}

// and implement it on my Product class
public class Product : IProduct {
    [Key]        
    public int Id {get;set;}

    public string Name {get;set;}

    [Write(false)]
    public ProductCategory Category {get;set;}

    int Category {get;set;}
}

如果您喜欢使用具有更改跟踪功能的Contrib,则可以使用此方法.如果你想和Rainbow一起工作,并且像导航属性一样有问题,那么你可以在play with my pull request.它的工作方式与WriteAttribute一样,只能与Rainbow一起使用.

如果您不是使用属性装饰课程的粉丝,则扩展项目不适合您.我知道还有另一个扩展项目可以让你做某种流畅的配置,但这并不是与github中的Dapper库(不包括在内).我的偏好是与核心图书馆合作,导致我调查整个图书馆,看看是否已经存在,或者是否可以改进以满足我的需要.这就是我在这里所做的和解释,对于彩虹和Contrib.

我希望这个贡献,我添加的非常简单的类,我显示的配置提示,以及引导我的场景,将会帮助将来有人使用Dapper,并且将有类似的设置.此外,这个答案将教育开发者更多的是Dapper可以做什么和不能做的.这个伟大的工具叫做Dapper deserves a better wiki,我希望这里的这个答案/文章有助于甚至在一个小的方式.

**如果我在这里写的内容已经写在某个地方,那么我在两周的时间内没有发现我一直在等待一个答案,那么我会很乐意让任何人联系我.现在已经有两个星期了,29个人看了我的问题没有建议任何链接或解决方案,所以我认为我在这里分享的信息是新的Dapper *

总结

以上是DEVMAX为你收集整理的orm – 如何使用Dapper.Rainbow(或可选地使用Dapper.Contrib)对具有导航属性的对象进行插入和更新全部内容。

如果觉得DEVMAX网站内容还不错,欢迎将DEVMAX网站推荐给好友。

orm – 如何使用Dapper.Rainbow(或可选地使用Dapper.Contrib)对具有导航属性的对象进行插入和更新的更多相关文章

  1. Django ORM F对象和Q对象查询

    Django提供了两个非常有用的工具:F对象和Q对象,方便了在一些特殊场景下的查询过程,这篇文章主要介绍了Django ORM F对象和Q对象查询,需要的朋友可以参考下

  2. 详解Java注解实现自己的ORM

    这篇文章主要介绍了Java注解实现自己的ORM知识,本文通过示例代码给大家讲解的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

  3. orm获取关联表里的属性值

    ORM是关系对象模型,本文给大家介绍orm获取关联表里的属性值,需要的朋友参考下吧

  4. laravel 数据迁移与 Eloquent ORM的实现方法

    laravel 提供了很实用的 Eloquent ORM 模型类,简单、直观的与数据库进行交互。同时使用数据迁移管理数据库,可以与团队进行共享以及编辑,本文详细的介绍了laravel 数据迁移与 Eloquent ORM的实现方法,感兴趣的可以了解一下

  5. 浅谈Node.js ORM框架Sequlize之表间关系

    下面小编就为大家带来一篇浅谈Node.js ORM框架Sequlize之表间关系。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  6. Laravel Eloquent ORM 多条件查询的例子

    今天小编就为大家分享一篇Laravel Eloquent ORM 多条件查询的例子,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

  7. Laravel5.7 Eloquent ORM快速入门详解

    这篇文章主要介绍了Laravel5.7 Eloquent ORM快速入门详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  8. laravel ORM关联关系中的 with和whereHas用法

    今天小编就为大家分享一篇laravel ORM关联关系中的 with和whereHas用法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

  9. Laravel框架Eloquent ORM新增数据、自定义时间戳及批量赋值用法详解

    这篇文章主要介绍了Laravel框架Eloquent ORM新增数据、自定义时间戳及批量赋值用法,结合实例形式详细分析了Laravel框架Eloquent ORM通过模型新增数据、时间戳设置、批量赋值模型、Create新增等相关使用方法,需要的朋友可以参考下

  10. Laravel框架Eloquent ORM修改数据操作示例

    这篇文章主要介绍了Laravel框架Eloquent ORM修改数据操作,结合实例形式详细分析了laravel框架更新数据的两种常见操作技巧,需要的朋友可以参考下

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部