orm – 如何使用Dapper.Rainbow(或可选地使用Dapper.Contrib)对
最近我开始研究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是否有功能.但是我没想到没有人会注意到这个声明(特别是粗体字):
…并提出一个替代方案,一个已经在Dapper库中的解决方案.我想我应该更清楚我的问题,并明确询问一个解决方案是否存在于整个Dapper library that is in github的某个地方.所以在更多的挖掘图书馆后,我发现有一个支持我的问题. Dapper.Contrib的路径 所有这些都与我的项目和彩虹工作良好,直到我需要更多的工作.我有一些表中有很多字段.如果我只是给Rainbow我的对象,那么它将对所有的字段进行更新,这不是很好.但是,这并不意味着我很快就跳出船,回到NH.所以在我实现自己的变更跟踪之前,我不想重新发明,特别是如果有人已经做了一个很好的工作,我已经在7月2日上网了.这个线程证实了我的知识,Rainbow不支持更改跟踪,但是另一个野兽,它被称为Dapper.Contrib.所以我开始尝试了. 所以我们再见面
我和彩虹有同样的问题. 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); 并且通过该调用,如果我不在界面中定义它,我将无法访问类别字段.但是如果我在我的界面中定义它,那么我会得到一个熟悉的错误
真的呢请停止. 判决 不需要担心,通过装饰接口成员,就像我们为该类做的一样,这个容易解决.所以使一切工作的最终配置应该是: 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 * (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |