当前位置: 首页 > news >正文

.NET 6 + Dapper + User-Defined Table Type

大家都知道,对于SQL Server IN是有限制条件的,如果IN里面的内容过多,在执行的时候会被自动截断,因而导致查询到的结果不是实际需要的结果。

select * from Payments where Id in (1,2,3,4,...)

为了解决上面的限制,可以改为利用用户自定义数据类型解决。

具体内容如下:

1. Create User-Defined Data Types

CREATE TYPE [dbo].[IdTable] AS TABLE([Id] [int] NOT NULL
)
GO

2. Create Store Procedure which use IdTable as Input paramter.

CREATE PROCEDURE [dbo].[SP_GET_PAYMENTS]                  @PaymentIds [dbo].[IdTable] READONLY                 
AS   
BEGIN  select p.Id,p.DueDate   from @PaymentIds tp     join Payments p with (nolock) on tp.Id=p.Id 
END  

3. Parameter convert to IdTable. SQLMapper Extension

  public static class Extensions{/// <summary>/// This extension converts an enumerable set to a Dapper TVP/// </summary>/// <typeparam name="T">type of enumerbale</typeparam>/// <param name="enumerable">list of values</param>/// <param name="typeName">database type name</param>/// <param name="orderedColumnNames">if more than one column in a TVP, /// columns order must mtach order of columns in TVP</param>/// <returns>a custom query parameter</returns>public static SqlMapper.ICustomQueryParameter AsTableValuedParameter<T>(this IEnumerable<T> enumerable,string typeName, IEnumerable<string> orderedColumnNames = null){var dataTable = new DataTable();if (typeof(T).IsValueType || typeof(T).FullName.Equals("System.String")){dataTable.Columns.Add(orderedColumnNames == null ?"NONAME" : orderedColumnNames.First(), typeof(T));foreach (T obj in enumerable){dataTable.Rows.Add(obj);}}else{PropertyInfo[] properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);PropertyInfo[] readableProperties = properties.Where(w => w.CanRead).ToArray();if (readableProperties.Length > 1 && orderedColumnNames == null)throw new ArgumentException("Ordered list of column names must be provided when TVP contains more than one column");var columnNames = (orderedColumnNames ??readableProperties.Select(s => s.Name)).ToArray();foreach (string name in columnNames){dataTable.Columns.Add(name, readableProperties.Single(s => s.Name.Equals(name)).PropertyType);}foreach (T obj in enumerable){dataTable.Rows.Add(columnNames.Select(s => readableProperties.Single(s2 => s2.Name.Equals(s)).GetValue(obj)).ToArray());}}return dataTable.AsTableValuedParameter(typeName);}}

4. Dapper code

Dapper version: 2.1.37

using System;
using System.Configuration;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using Dapper;
using log4net;
using Microsoft.Data.SqlClient;
using static Dapper.SqlMapper;public List<T> QueryEntitiesNoUTC<T>(string sqlCommand, object parameters, CommandType commandType, int commandTimeout = 60){using (SqlConnection Connection = GetSqlConnection(ConfigurationManager.ConnectionStrings["Default"].ConnectionString)){try{Connection.Open();List<T> returnValues = Connection.Query<T>(sqlCommand, parameters, commandType: commandType, commandTimeout: GetCommandTimeout(commandTimeout)).ToList<T>();Connection.Close();Connection.Dispose();return returnValues;}catch (Exception e){Log.Error(e);throw;}finally{Connection.Close();Connection.Dispose();}}}

5. C# call Demo

        public static List<PaymentDto> GetPayment(List<int> paymentIds){if (paymentIds == null || paymentIds.Count == 0){return new();}var param = new { PaymentIds = paymentIds.AsTableValuedParameter("dbo.IdTable", new List<string>() { "Id" }) };var result = dapperHelper.QueryEntitiesNoUTC<PaymentDto>("SP_GET_PAYMENTS", param, CommandType.StoredProcedure, SqlConstants.GetBiggerRecordsTimeoutSeconds);return result;}

如果是多个参数:

var param = new { PaymentIds= paymentIds.AsTableValuedParameter("dbo.IdTable", new List<string>() { "Id" }), Status= status};

相关文章:

  • ElasticSearch深入解析(三):Elasticsearch 7的安装与配置、Kibana安装
  • Kafka 核心使用机制总结
  • ADW600防护等级与电气安全设计要点详解
  • MCU开发学习记录11 - ADC学习与实践(HAL库) - 单通道ADC采集、多通道ADC采集、定时器触发连续ADC采集 - STM32CubeMX
  • 从零到精通:探索GoFrame框架中gcron的定时任务之道 —— 优势、实践与踩坑经验
  • Java的JUC详细全解
  • Kotlin高阶函数 vs Lambda表达式:关键区别与协作关系
  • 深度探究获取淘宝商品数据的途径|API接口|批量自动化采集商品数据
  • 小学数学出题器:自动化作业生成
  • 智能指针(weak_ptr )之三
  • equals与hashCode的关系探究
  • 一 、环境的安装 Anaconda + Pycharm + PaddlePaddle
  • 火山云生态的体现
  • 容器内部无法访问宿主机服务的原因及解决方法
  • 深入解析:RocketMQ、RabbitMQ和Kafka的区别与使用场景
  • MySQL的日志--Redo Log【学习笔记】
  • opencv--图像
  • Synternet数据流正式上线Google Cloud Web3
  • Vue3 模板语法
  • AIGC架构与原理
  • 一夜跌去200美元,黄金巨震冲上热搜!涨势已近尾声?
  • 郑庆华任同济大学党委书记
  • 魔都眼·上海车展②|小鹏汽车:何小鹏携手机器人车模首秀
  • 洛阳白马寺内的狄仁杰墓挂上公示牌争论尘埃落定?瀍河区文旅局称已确认
  • 为青少年写新中国成立的故事,刘统遗著《火种》出版
  • 上海又一住宅新盘“日光”!今年已有9个新房项目触发积分