使用 Dapper 执行插入和更新
我对使用 Dapper 很感兴趣 - 但据我所知它只支持查询和执行。我没有看到 Dapper 包含插入和更新对象的方法。
鉴于我们的项目(大多数项目?)需要进行插入和更新,那么与 dapper 一起进行插入和更新的最佳实践是什么?
最好我们不必求助于 ADO.NET 参数构建方法等。
此时我能想到的最佳答案是使用 LinqToSQL 进行插入和更新。有更好的答案吗?
I am interested in using Dapper - but from what I can tell it only supports Query and Execute. I do not see that Dapper includes a way of Inserting and Updating objects.
Given that our project (most projects?) need to do inserts and updates, what is the best practice for doing Inserts and Updates alongside dapper?
Preferably we would not have to resort to the ADO.NET method of parameter building, etc.
The best answer I can come up with at this point is to use LinqToSQL for inserts and updates. Is there a better answer?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
我们正在考虑构建一些助手,仍在决定 API 以及是否进入核心。请参阅:https://code.google.com/archive/p /dapper-dot-net/issues/6 了解进度。
同时,您可以执行以下
操作等
另请参阅我的博客文章: 那个烦人的 INSERT 问题
更新
正如评论中所指出的,现在有几个扩展可用在 <这些
IDbConnection
扩展形式的 href="https://github.com/DapperLib/Dapper.Contrib" rel="noreferrer">Dapper.Contrib 项目方法:We are looking at building a few helpers, still deciding on APIs and if this goes in core or not. See: https://code.google.com/archive/p/dapper-dot-net/issues/6 for progress.
In the mean time you can do the following
etcetera
See also my blog post: That annoying INSERT problem
Update
As pointed out in the comments, there are now several extensions available in the Dapper.Contrib project in the form of these
IDbConnection
extension methods:使用 Dapper 执行 CRUD 操作是一项简单的任务。我提到的下面的示例应该可以帮助您进行 CRUD 操作。
CRUD 代码:
方法 #1: 当您插入来自不同实体的值时,将使用此方法。
方法#2:当您的实体属性与 SQL 列具有相同名称时,使用此方法。因此,Dapper 作为 ORM 将实体属性与匹配的 SQL 列进行映射。
CRUD 代码:
CRUD 代码:
CRUD 代码:
Performing CRUD operations using Dapper is an easy task. I have mentioned the below examples that should help you in CRUD operations.
Code for CRUD:
Method #1: This method is used when you are inserting values from different entities.
Method #2: This method is used when your entity properties have the same names as the SQL columns. So, Dapper being an ORM maps entity properties with the matching SQL columns.
Code for CRUD:
Code for CRUD:
Code for CRUD:
你可以这样做:
Caius 添加的编辑:
请注意,没有必要以这种“在操作之前/之后立即”的方式打开/关闭连接:如果您的连接关闭,Dapper 会打开它。如果您的连接处于打开状态,Dapper 会将其保持打开状态。
如果您有许多操作要执行/您正在使用事务,请自行打开连接。如果您要做的只是打开/执行/关闭,请让 Dapper 来完成。
另外,没有必要创建匿名类型;只需使参数名称与保存数据的任何类型中的属性名称相匹配,然后传递该类型,而不是将其解压为匿名类型。
上面的代码可以这样写:
you can do it in such way:
Edit added by Caius:
Note that it's not necessary to open/close the connection in this "immediately before/after the operation" way: if your connection is closed, Dapper opens it. If your connection is open, Dapper leaves it open.
Open the connection yourself if you e.g. have many operations to perform/you're using a transaction. Leave Dapper to do it if all you'll do is open/execute/close.
Also, it's unnecessary to make an anonymous type; just make your parameters names match your property names in whatever type holds your data, and pass that type rather than unpacking it to an anonymous type.
The code above can be written thus:
使用 Dapper.Contrib 就这么简单:
插入列表:
插入单个:
更新列表:
更新单个:
来源:https://github.com/StackExchange/Dapper/tree/master/Dapper.Contrib
Using Dapper.Contrib it is as simple as this:
Insert list:
Insert single:
Update list:
Update single:
Source: https://github.com/StackExchange/Dapper/tree/master/Dapper.Contrib
您还可以将 dapper 与存储过程和通用方式一起使用,从而轻松管理所有内容。
定义您的连接:
创建一个接口来定义您实际需要的 Dapper 方法:
实现接口:
您现在可以根据需要从模型调用:
您也可以传递参数:
现在从您的控制器调用:
希望它可以防止您的代码重复并提供安全性;
You can also use dapper with a stored procedure and generic way by which everything easily manageable.
Define your connection:
Create an interface to define Dapper methods those you actually need:
Implement the interface:
You can now call from model as your need:
You can also passed parameters as well:
Now call from your controllers:
Hope it's prevent your code repetition and provide security;
我宁愿建议您自己编写查询,而不是使用任何第三方库进行查询操作。因为使用任何其他第 3 方包都会剥夺使用简洁的主要优势,即编写查询的灵活性。
现在,为整个对象编写插入或更新查询时存在问题。为此,可以简单地创建如下帮助程序:
InsertQueryBuilder:
现在,只需传递要插入的列的名称,就会自动创建整个查询,如下所示:
您还可以修改该函数以返回整个 INSERT 语句 :传递表名参数。
确保类属性名称与数据库中的字段名称匹配。然后,只有您可以传递整个 obj(如我们示例中的 userObj),并且值将自动映射。
以同样的方式,您也可以拥有 UPDATE 查询的辅助函数:
并像这样使用它:
虽然在这些辅助函数中,您也需要传递要插入或更新的字段的名称,但至少您有完整的控制查询,还可以根据需要包含不同的 WHERE 子句。
通过这个辅助函数,您将节省以下几行代码:
对于插入查询:
对于更新查询:
似乎有几行代码的区别,但是当涉及到对具有多于一行的表执行插入或更新操作时10个领域,一目了然。
您可以使用 nameof 运算符在函数中传递字段名称以避免拼写错误
而不是:
您可以编写:
Instead of using any 3rd party library for query operations, I would rather suggest writing queries on your own. Because using any other 3rd party packages would take away the main advantage of using dapper i.e. flexibility to write queries.
Now, there is a problem with writing Insert or Update query for the entire object. For this, one can simply create helpers like below:
InsertQueryBuilder:
Now, by simply passing the name of the columns to insert, the whole query will be created automatically, like below:
You can also modify the function to return the entire INSERT statement by passing the TableName parameter.
Make sure that the Class property names match with the field names in the database. Then only you can pass the entire obj (like userObj in our case) and values will be mapped automatically.
In the same way, you can have the helper function for UPDATE query as well:
And use it like:
Though in these helper functions also, you need to pass the name of the fields you want to insert or update but at least you have full control over the query and can also include different WHERE clauses as and when required.
Through this helper functions, you will save the following lines of code:
For Insert Query:
For Update Query:
There seems to be a difference of few lines of code, but when it comes to performing insert or update operation with a table having more than 10 fields, one can feel the difference.
You can use the nameof operator to pass the field name in the function to avoid typos
Instead of:
You can write:
存储过程 + Dapper 方法或 SQL insert 语句 + Dapper 可以完成这项工作,但它并不能完美实现 ORM 的概念,即动态映射数据模型与 SQL 表列,因为如果使用上述两种方法之一,您仍然需要硬编码存储过程参数或 SQL 插入语句中的某些列名称值。
为了解决尽量减少代码修改的问题,可以使用 Dapper.Contrib 来支持SQL 插入,这里是官方指南,下面是示例设置和代码
第 1 步
使用
Dapper.Contrib.Extensions
在 C# 中设置类模型:[Table]
属性将指向 SQL 框中所需的表名称,[ExplicitKey]
属性将告诉 Dapper 该模型属性是 SQL 表中的主键。第 2 步
设置 SQL 数据库/表,如下所示:
第 3 步
现在构建您的 C# 代码,如下所示,您需要使用这些命名空间:
代码:
Stored procedure + Dapper method or SQL insert statement + Dapper do the work, but it do not perfectly fulfill the concept of ORM which dynamic mapping data model with SQL table column, because if using one of the above 2 approaches, you still need hard code some column name value in your stored procedure parameter or SQL insert statement.
To solve the concern of minimize code modification, you can use Dapper.Contrib to support SQL insert, here is the official guide and below was the sample setup and code
Step 1
Set up your class model in C#, by using
Dapper.Contrib.Extensions
:[Table]
attribute will point to the desired table name in your SQL box,[ExplicitKey]
attribute will tell Dapper this model properties is a primary key in your SQL table.Step 2
Setup you SQL database/table something like this:
Step 3
Now build your C# code as something like below, you need to use these namespaces:
Code:
你可以试试这个:
You can try this:
这是一个使用
Repository Pattern
的简单示例:在
UserRepository
中:注意:
NpgsqlConnection
用于获取ConnectionString
PostgreSQL数据库Here is a simple example with
Repository Pattern
:And in
UserRepository
:Note :
NpgsqlConnection
used for getting theConnectionString
of PostgreSQL database