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));
}
}
}
}
}