using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Data; using System.Data.Common; using System.Linq; using System.Reflection; using Znyc.Recruitment.Admin.Commons.Extend; using Znyc.Recruitment.Admin.Commons.Extensions; using Znyc.Recruitment.Admin.Commons.Helpers; using Znyc.Recruitment.Admin.Commons.IDbContext; using Znyc.Recruitment.Admin.Commons.Pages; namespace Znyc.Recruitment.Admin.Commons.DbContextCore { /// /// Sql Server数据库上下文 /// public class SqlServerDbContext : BaseDbContext, ISqlServerDbContext { /// /// 批量插入 /// /// /// 数据实体集合 /// 如果为 null,则使用 TModel 名称作为 destinationTableName /// public override void BulkInsert(IList entities, string destinationTableName = null) { if (entities == null || !entities.Any()) { return; } if (string.IsNullOrEmpty(destinationTableName)) { string mappingTableName = typeof(T).GetCustomAttribute()?.Name; destinationTableName = string.IsNullOrEmpty(mappingTableName) ? typeof(T).Name : mappingTableName; } SqlBulkInsert(entities, destinationTableName); } /// /// 分页查询,SQL语句查询,返回指定输出对象集合 /// /// 查询对象实体 /// 返回/输出实体 /// sql语句 /// 排序条件 /// 当前页 /// 每页显示数量 /// /// public override PageResult SqlQueryByPagination(string sql, string[] orderBys, int pageIndex, int pageSize, Action eachAction = null) { int total = SqlQuery($"select count(1) from ({sql}) as s").FirstOrDefault(); List jsonResults = SqlQuery( $"select * from (select *,row_number() over (order by {string.Join(",", orderBys)}) as RowId from ({sql}) as s) as t where RowId between {pageSize * (pageIndex - 1) + 1} and {pageSize * pageIndex} order by {string.Join(",", orderBys)}") .ToList(); if (eachAction != null) { jsonResults = jsonResults.Each(eachAction).ToList(); } return new PageResult { CurrentPage = pageIndex, ItemsPerPage = pageSize, TotalItems = total }; } /// /// 分页查询,SQL语句查询,返回数据实体集合 /// /// 查询对象实体 /// sql语句 /// 排序条件 /// 当前页 /// 每页显示数量 /// 查询SQL参数 /// public override PageResult SqlQueryByPagination(string sql, string[] orderBys, int pageIndex, int pageSize, params DbParameter[] parameters) { int total = (int)this.ExecuteScalar($"select count(1) from ({sql}) as s"); List jsonResults = GetDataTable( $"select * from (select *,row_number() over (order by {string.Join(",", orderBys)}) as RowId from ({sql}) as s) as t where RowId between {pageSize * (pageIndex - 1) + 1} and {pageSize * pageIndex} order by {string.Join(",", orderBys)}") .ToList(); return new PageResult { CurrentPage = pageIndex, ItemsPerPage = pageSize, TotalItems = total, Items = jsonResults }; } /// /// 根据sql语句返回DataTable数据 /// /// Sql语句 /// 执行超时时间,默认30毫秒 /// DbParameter[]参数 /// public override DataTable GetDataTable(string sql, int cmdTimeout = 30, params DbParameter[] parameters) { return GetDataTables(sql, cmdTimeout, parameters).FirstOrDefault(); } /// /// 根据sql语句返回List数据 /// /// Sql语句 /// 执行超时时间,默认30毫秒 /// DbParameter[] 参数 /// public override List GetDataTables(string sql, int cmdTimeout = 30, params DbParameter[] parameters) { List dts = new List(); //TODO: connection 不能dispose 或者 用using,否则下次获取connection会报错提示“the connectionstring property has not been initialized。” DbConnection connection = Database.GetDbConnection(); if (connection.State != ConnectionState.Open) { connection.Open(); } using (SqlCommand cmd = new SqlCommand(sql, (SqlConnection)connection)) { cmd.CommandTimeout = cmdTimeout; if (parameters != null && parameters.Length > 0) { cmd.Parameters.AddRange(parameters); } using (SqlDataAdapter da = new SqlDataAdapter(cmd)) { using (DataSet ds = new DataSet()) { da.Fill(ds); foreach (DataTable table in ds.Tables) { dts.Add(table); } } } } connection.Close(); return dts; } /// /// 批量插入 /// /// /// 数据实体集合 /// 如果为 null,则使用 TModel 名称作为 destinationTableName /// private void SqlBulkInsert(IList entities, string destinationTableName = null) where T : class { using (DataTable dt = entities.ToDataTable()) { dt.TableName = destinationTableName; SqlConnection conn = (SqlConnection)Database.GetDbConnection(); if (conn.State != ConnectionState.Open) { conn.Open(); } using (SqlTransaction tran = conn.BeginTransaction()) { try { SqlBulkCopy bulk = new SqlBulkCopy(conn, SqlBulkCopyOptions.Default, tran) { BatchSize = entities.Count, DestinationTableName = dt.TableName }; GenerateColumnMappings(bulk.ColumnMappings); bulk.WriteToServerAsync(dt); tran.Commit(); } catch (Exception) { tran.Rollback(); throw; } } conn.Close(); } } /// /// 字段与实体关系映射 /// /// /// private void GenerateColumnMappings(SqlBulkCopyColumnMappingCollection mappings) where T : class { PropertyInfo[] properties = typeof(T).GetProperties(); foreach (PropertyInfo property in properties) { if (property.GetCustomAttributes().Any()) { mappings.Add(new SqlBulkCopyColumnMapping(property.Name, typeof(T).Name + property.Name)); } else { mappings.Add(new SqlBulkCopyColumnMapping(property.Name, property.Name)); } } } } }