You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
DSWMS/Vue.Net/VOL.Core/BaseProvider/RepositoryBase.cs

926 lines
38 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using Castle.Components.DictionaryAdapter;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Storage;
using System;
using System.Collections.Generic;
using System.Data.Common;
//using System.Data.SqlClient;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Data.SqlClient;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;
using VOL.Core.Dapper;
using VOL.Core.DBManager;
using VOL.Core.EFDbContext;
using VOL.Core.Enums;
using VOL.Core.Extensions;
using VOL.Core.Utilities;
using VOL.Entity;
using VOL.Entity.SystemModels;
namespace VOL.Core.BaseProvider
{
public abstract class RepositoryBase<TEntity> where TEntity : BaseEntity
{
public RepositoryBase()
{
}
public RepositoryBase(VOLContext dbContext)
{
this.DefaultDbContext = dbContext ?? throw new Exception("dbContext未实例化。");
}
private VOLContext DefaultDbContext { get; set; }
private VOLContext EFContext
{
get
{
DBServerProvider.GetDbContextConnection<TEntity>(DefaultDbContext);
return DefaultDbContext;
}
}
public virtual VOLContext DbContext
{
get { return DefaultDbContext; }
}
private DbSet<TEntity> DBSet
{
get { return EFContext.Set<TEntity>(); }
}
public ISqlDapper DapperContext
{
get { return DBServerProvider.GetSqlDapper<TEntity>(); }
}
/// <summary>
/// 执行事务
/// </summary>
/// <param name="action">如果返回false则回滚事务(可自行定义规则)</param>
/// <returns></returns>
public virtual WebResponseContent DbContextBeginTransaction(Func<WebResponseContent> action)
{
WebResponseContent webResponse = new WebResponseContent();
using (IDbContextTransaction transaction = DefaultDbContext.Database.BeginTransaction())
{
try
{
webResponse = action();
if (webResponse.Status)
{
transaction.Commit();
}
else
{
transaction.Rollback();
}
return webResponse;
}
catch (Exception ex)
{
transaction.Rollback();
return new WebResponseContent().Error(ex.Message);
}
}
}
public virtual bool Exists<TExists>(Expression<Func<TExists, bool>> predicate) where TExists : class
{
return EFContext.Set<TExists>().Any(predicate);
}
public virtual Task<bool> ExistsAsync<TExists>(Expression<Func<TExists, bool>> predicate) where TExists : class
{
return EFContext.Set<TExists>().AnyAsync(predicate);
}
public virtual bool Exists(Expression<Func<TEntity, bool>> predicate)
{
return DBSet.Any(predicate);
}
public virtual Task<bool> ExistsAsync(Expression<Func<TEntity, bool>> predicate)
{
return DBSet.AnyAsync(predicate);
}
public virtual List<TFind> Find<TFind>(Expression<Func<TFind, bool>> predicate) where TFind : class
{
return EFContext.Set<TFind>().Where(predicate).ToList();
}
public virtual Task<TFind> FindAsyncFirst<TFind>(Expression<Func<TFind, bool>> predicate) where TFind : class
{
return FindAsIQueryable<TFind>(predicate).FirstOrDefaultAsync();
}
public virtual Task<TEntity> FindAsyncFirst(Expression<Func<TEntity, bool>> predicate)
{
return FindAsIQueryable<TEntity>(predicate).FirstOrDefaultAsync();
}
public virtual Task<List<TFind>> FindAsync<TFind>(Expression<Func<TFind, bool>> predicate) where TFind : class
{
return FindAsIQueryable<TFind>(predicate).ToListAsync();
}
public virtual Task<List<TEntity>> FindAsync(Expression<Func<TEntity, bool>> predicate)
{
return FindAsIQueryable(predicate).ToListAsync();
}
public virtual Task<TEntity> FindFirstAsync(Expression<Func<TEntity, bool>> predicate)
{
return FindAsIQueryable(predicate).FirstOrDefaultAsync();
}
public virtual Task<List<T>> FindAsync<T>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, T>> selector)
{
return FindAsIQueryable(predicate).Select(selector).ToListAsync();
}
public virtual Task<T> FindFirstAsync<T>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, T>> selector)
{
return FindAsIQueryable(predicate).Select(selector).FirstOrDefaultAsync();
}
public virtual IQueryable<TFind> FindAsIQueryable<TFind>(Expression<Func<TFind, bool>> predicate) where TFind : class
{
return EFContext.Set<TFind>().Where(predicate);
}
public virtual List<TEntity> Find<Source>(IEnumerable<Source> sources,
Func<Source, Expression<Func<TEntity, bool>>> predicate)
where Source : class
{
return FindAsIQueryable(sources, predicate).ToList();
}
public virtual List<TResult> Find<Source, TResult>(IEnumerable<Source> sources,
Func<Source, Expression<Func<TEntity, bool>>> predicate,
Expression<Func<TEntity, TResult>> selector)
where Source : class
{
return FindAsIQueryable(sources, predicate).Select(selector).ToList();
}
/// <summary>
/// 多条件查询
/// </summary>
/// <typeparam name="Source"></typeparam>
/// <param name="sources"></param>
/// <param name="predicate"></param>
/// <returns></returns>
public virtual IQueryable<TEntity> FindAsIQueryable<Source>(IEnumerable<Source> sources,
Func<Source, Expression<Func<TEntity, bool>>> predicate)
where Source : class
{
// EFContext.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.TrackAll;
Expression<Func<TEntity, bool>> resultPredicate = x => 1 == 2;
foreach (Source source in sources)
{
Expression<Func<TEntity, bool>> expression = predicate(source);
resultPredicate = (resultPredicate).Or<TEntity>((expression));
}
return EFContext.Set<TEntity>().Where(resultPredicate);
}
public virtual List<T> Find<T>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, T>> selector)
{
return DBSet.Where(predicate).Select(selector).ToList();
}
/// <summary>
/// 单表查询
/// </summary>
/// <param name="predicate"></param>
/// <returns></returns>
public virtual List<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
{
return FindAsIQueryable(predicate).ToList();
}
/// <summary>
///
/// </summary>
/// <param name="predicate"></param>
/// <param name=""></param>
/// <param name="orderBy">排序字段</param>
/// <returns></returns>
public virtual TEntity FindFirst(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, Dictionary<object, QueryOrderBy>>> orderBy = null)
{
return FindAsIQueryable(predicate, orderBy).FirstOrDefault();
}
public IQueryable<TEntity> FindAsIQueryable(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, Dictionary<object, QueryOrderBy>>> orderBy = null)
{
if (orderBy != null)
return DbContext.Set<TEntity>().Where(predicate).GetIQueryableOrderBy(orderBy.GetExpressionToDic());
return DbContext.Set<TEntity>().Where(predicate);
}
public IIncludableQueryable<TEntity, TProperty> Include<TProperty>(Expression<Func<TEntity, TProperty>> incluedProperty)
{
return DbContext.Set<TEntity>().Include(incluedProperty);
}
/// <summary>
/// 通过条件查询返回指定列的数据(将TEntity映射到匿名或实体T)
///var result = Sys_UserRepository.GetInstance.Find(x => x.UserName == loginInfo.userName, p => new { uname = p.UserName });
/// <summary>
///
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="pageIndex"></param>
/// <param name="pagesize"></param>
/// <param name="rowcount"></param>
/// <param name="predicate">查询条件</param>
/// <param name="orderBySelector">多个排序字段key为字段value为升序/降序</param>
/// <returns></returns>
public virtual IQueryable<TFind> IQueryablePage<TFind>(int pageIndex, int pagesize, out int rowcount, Expression<Func<TFind, bool>> predicate, Expression<Func<TEntity, Dictionary<object, QueryOrderBy>>> orderBy, bool returnRowCount = true) where TFind : class
{
pageIndex = pageIndex <= 0 ? 1 : pageIndex;
pagesize = pagesize <= 0 ? 10 : pagesize;
if (predicate == null)
{
predicate = x => 1 == 1;
}
var _db = DbContext.Set<TFind>();
rowcount = returnRowCount ? _db.Count(predicate) : 0;
return DbContext.Set<TFind>().Where(predicate)
.GetIQueryableOrderBy(orderBy.GetExpressionToDic())
.Skip((pageIndex - 1) * pagesize)
.Take(pagesize);
}
/// <summary>
/// 分页排序
/// </summary>
/// <param name="queryable"></param>
/// <param name="pageIndex"></param>
/// <param name="pagesize"></param>
/// <param name="rowcount"></param>
/// <param name="orderBy"></param>
/// <returns></returns>
public virtual IQueryable<TEntity> IQueryablePage(IQueryable<TEntity> queryable, int pageIndex, int pagesize, out int rowcount, Dictionary<string, QueryOrderBy> orderBy, bool returnRowCount = true)
{
pageIndex = pageIndex <= 0 ? 1 : pageIndex;
pagesize = pagesize <= 0 ? 10 : pagesize;
rowcount = returnRowCount ? queryable.Count() : 0;
return queryable.GetIQueryableOrderBy<TEntity>(orderBy)
.Skip((pageIndex - 1) * pagesize)
.Take(pagesize);
}
public virtual List<TResult> QueryByPage<TResult>(int pageIndex, int pagesize, out int rowcount, Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, Dictionary<object, QueryOrderBy>>> orderBy, Expression<Func<TEntity, TResult>> selectorResult, bool returnRowCount = true)
{
return IQueryablePage<TEntity>(pageIndex, pagesize, out rowcount, predicate, orderBy, returnRowCount).Select(selectorResult).ToList();
}
public List<TEntity> QueryByPage(int pageIndex, int pagesize, out int rowcount, Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, Dictionary<object, QueryOrderBy>>> orderBy, bool returnRowCount = true)
{
return IQueryablePage<TEntity>(pageIndex, pagesize, out rowcount, predicate, orderBy).ToList();
}
public virtual List<TResult> QueryByPage<TResult>(int pageIndex, int pagesize, Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, Dictionary<object, QueryOrderBy>>> orderBy, Expression<Func<TEntity, TResult>> selectorResult = null)
{
return IQueryablePage<TEntity>(pageIndex, pagesize, out int rowcount, predicate, orderBy).Select(selectorResult).ToList();
}
/// <summary>
/// 更新表数据
/// </summary>
/// <param name="entity"></param>
/// <param name="saveChanges">是否保存</param>
/// <param name="properties">格式 Expression<Func<entityt, object>> expTree = x => new { x.字段1, x.字段2 };</param>
public virtual int Update(TEntity entity, Expression<Func<TEntity, object>> properties, bool saveChanges = false)
{
return Update<TEntity>(entity, properties, saveChanges);
}
public virtual int Update<TSource>(TSource entity, Expression<Func<TSource, object>> properties, bool saveChanges = false) where TSource : class
{
return UpdateRange(new List<TSource>
{
entity
}, properties, saveChanges);
}
public virtual int Update<TSource>(TSource entity, string[] properties, bool saveChanges = false) where TSource : class
{
return UpdateRange<TSource>(new List<TSource>() { entity }, properties, saveChanges);
}
public virtual int Update<TSource>(TSource entity, bool saveChanges = false) where TSource : class
{
return UpdateRange<TSource>(new List<TSource>() { entity }, new string[0], saveChanges);
}
public virtual int UpdateRange<TSource>(IEnumerable<TSource> entities, Expression<Func<TSource, object>> properties, bool saveChanges = false) where TSource : class
{
return UpdateRange<TSource>(entities, properties?.GetExpressionProperty(), saveChanges);
}
public virtual int UpdateRange<TSource>(IEnumerable<TSource> entities, bool saveChanges = false) where TSource : class
{
return UpdateRange<TSource>(entities, new string[0], saveChanges);
}
/// <summary>
/// 更新表数据
/// </summary>
/// <param name="models"></param>
/// <param name="properties">格式 Expression<Func<entityt, object>> expTree = x => new { x.字段1, x.字段2 };</param>
public int UpdateRange<TSource>(IEnumerable<TSource> entities, string[] properties, bool saveChanges = false) where TSource : class
{
if (properties != null && properties.Length > 0)
{
PropertyInfo[] entityProperty = typeof(TSource).GetProperties();
string keyName = entityProperty.GetKeyName();
if (properties.Contains(keyName))
{
properties = properties.Where(x => x != keyName).ToArray();
}
properties = properties.Where(x => entityProperty.Select(s => s.Name).Contains(x)).ToArray();
}
foreach (TSource item in entities)
{
if (properties == null || properties.Length == 0)
{
DbContext.Entry<TSource>(item).State = EntityState.Modified;
continue;
}
var entry = DbContext.Entry(item);
properties.ToList().ForEach(x =>
{
entry.Property(x).IsModified = true;
});
}
if (!saveChanges) return 0;
//2020.04.24增加更新时并行重试处理
try
{
// Attempt to save changes to the database
return DbContext.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
int affectedRows = 0;
foreach (var entry in ex.Entries)
{
var proposedValues = entry.CurrentValues;
var databaseValues = entry.GetDatabaseValues();
//databaseValues == null说明数据已被删除
if (databaseValues != null)
{
foreach (var property in properties == null
|| properties.Length == 0 ? proposedValues.Properties
: proposedValues.Properties.Where(x => properties.Contains(x.Name)))
{
var proposedValue = proposedValues[property];
var databaseValue = databaseValues[property];
}
affectedRows++;
entry.OriginalValues.SetValues(databaseValues);
}
}
if (affectedRows == 0) return 0;
return DbContext.SaveChanges();
}
}
/// <summary>
///
/// </summary>
/// <param name="entity"></param>
/// <param name="updateDetail">是否修改明细</param>
/// <param name="delNotExist">是否删除明细不存在的数据</param>
/// <param name="updateMainFields">主表指定修改字段</param>
/// <param name="updateDetailFields">明细指定修改字段</param>
/// <param name="saveChange">是否保存</param>
/// <returns></returns>
public virtual WebResponseContent UpdateRange<Detail>(TEntity entity,
bool updateDetail = false,
bool delNotExist = false,
Expression<Func<TEntity, object>> updateMainFields = null,
Expression<Func<Detail, object>> updateDetailFields = null,
bool saveChange = false) where Detail : class
{
WebResponseContent webResponse = new WebResponseContent();
Update(entity, updateMainFields);
string message = "";
if (updateDetail)
{
PropertyInfo[] properties = typeof(TEntity).GetProperties();
PropertyInfo detail = properties.Where(x => x.PropertyType.Name == "List`1").ToList().FirstOrDefault();
if (detail != null)
{
PropertyInfo key = properties.GetKeyProperty();
object obj = detail.GetValue(entity);
Type detailType = typeof(TEntity).GetCustomAttribute<EntityAttribute>().DetailTable[0];
message = UpdateDetail<Detail>(obj as List<Detail>, key.Name, key.GetValue(entity), updateDetailFields, delNotExist);
}
}
if (!saveChange) return webResponse.OK();
DbContext.SaveChanges();
return webResponse.OK("修改成功,明细" + message, entity);
}
private string UpdateDetail<TDetail>(List<TDetail> list,
string keyName,
object keyValue,
Expression<Func<TDetail, object>> updateDetailFields = null,
bool delNotExist = false) where TDetail : class
{
if (list == null) return "";
PropertyInfo property = typeof(TDetail).GetKeyProperty();
string detailKeyName = property.Name;
DbSet<TDetail> details = DbContext.Set<TDetail>();
Expression<Func<TDetail, object>> selectExpression = detailKeyName.GetExpression<TDetail, object>();
Expression<Func<TDetail, bool>> whereExpression = keyName.CreateExpression<TDetail>(keyValue, LinqExpressionType.Equal);
List<object> detailKeys = details.Where(whereExpression).Select(selectExpression).ToList();
//获取主键默认值
string keyDefaultVal = property.PropertyType
.Assembly
.CreateInstance(property.PropertyType.FullName).ToString();
int addCount = 0;
int editCount = 0;
int delCount = 0;
PropertyInfo mainKeyProperty = typeof(TDetail).GetProperty(keyName);
List<object> keys = new List<object>();
list.ForEach(x =>
{
var set = DbContext.Set<TDetail>();
object val = property.GetValue(x);
//主键是默认值的为新增的数据
if (val.ToString() == keyDefaultVal)
{
x.SetCreateDefaultVal();
//设置主表的值,也可以不设置
mainKeyProperty.SetValue(x, keyValue);
details.Add(x);
addCount++;
}
else//修改的数据
{
//获取所有修改的key,如果从数据库查来的key,不在修改中的key则为删除的数据
keys.Add(val);
x.SetModifyDefaultVal();
Update<TDetail>(x, updateDetailFields);
// repository.DbContext.Entry<TDetail>(x).State = EntityState.Modified;
editCount++;
}
});
//删除
if (delNotExist)
{
detailKeys.Where(x => !keys.Contains(x)).ToList().ForEach(d =>
{
delCount++;
TDetail detail = Activator.CreateInstance<TDetail>();
property.SetValue(detail, d);
DbContext.Entry<TDetail>(detail).State = EntityState.Deleted;
for (int i = 0; i < list.Count(); i++)
{
if (property.GetValue(list[i]) == d)
{
list.RemoveAt(i);
}
}
});
}
return $"修改[{editCount}]条,新增[{addCount}]条,删除[{delCount}]条";
}
public virtual void Delete(TEntity model, bool saveChanges)
{
DBSet.Remove(model);
if (saveChanges)
{
DbContext.SaveChanges();
}
}
/// <summary>
/// 通过主键批量删除
/// </summary>
/// <param name="keys">主键key</param>
/// <param name="delList">是否连明细一起删除</param>
/// <returns></returns>
public virtual int Delete(object[] keys, bool delList = false)
{
Type entityType = typeof(TEntity);
string tKey = entityType.GetKeyProperty().Name;
FieldType fieldType = entityType.GetFieldType();
string joinKeys = (fieldType == FieldType.Int || fieldType == FieldType.BigInt)
? string.Join(",", keys)
: $"'{string.Join("','", keys)}'";
string sql = $"DELETE FROM {entityType.Name } where {tKey} in ({joinKeys});";
if (delList)
{
Type detailType = entityType.GetCustomAttribute<EntityAttribute>().DetailTable?[0];
if (detailType != null)
sql = sql + $"DELETE FROM {detailType.Name} where {tKey} in ({joinKeys});";
}
return ExecuteSqlCommand(sql);
}
public virtual void Add(TEntity entities, bool saveChanges = false)
{
AddRange(new List<TEntity>() { entities }, saveChanges);
}
public virtual void Add(TEntity entities, string[] properties, bool saveChanges = false)
{
AddRange(new List<TEntity>() { entities }, saveChanges);
}
public virtual void AddRange(IEnumerable<TEntity> entities, bool saveChanges = false)
{
DBSet.AddRange(entities);
if (saveChanges) DbContext.SaveChanges();
}
public virtual void AddRange<T>(IEnumerable<T> entities, bool saveChanges = false)
where T : class
{
DbContext.Set<T>().AddRange(entities);
if (saveChanges) DbContext.SaveChanges();
}
public virtual void AddRange<TSource>(IEnumerable<TSource> entities, Expression<Func<TSource, object>> properties, bool saveChanges = false) where TSource : class
{
AddRange<TSource>(entities, properties?.GetExpressionProperty(), saveChanges);
}
public virtual void AddRange<TSource>(IEnumerable<TSource> entities, string[] properties, bool saveChanges = false) where TSource : class
{
if (properties != null && properties.Length > 0)
{
PropertyInfo[] entityProperty = typeof(TSource).GetProperties();
//string keyName = entityProperty.GetKeyName();
//if (properties.Contains(keyName))
//{
// properties = properties.Where(x => x != keyName).ToArray();
//}
properties = properties.Where(x => entityProperty.Select(s => s.Name).Contains(x)).ToArray();
}
foreach (TSource item in entities)
{
if (properties == null || properties.Length == 0)
{
DbContext.Entry<TSource>(item).State = EntityState.Added;
continue;
}
var entry = DbContext.Entry(item);
properties.ToList().ForEach(x =>
{
entry.Property(x).IsModified = true;
});
}
if (!saveChanges) { }
else
{
//2020.04.24增加更新时并行重试处理
try
{
// Attempt to save changes to the database
DbContext.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
int affectedRows = 0;
foreach (var entry in ex.Entries)
{
var proposedValues = entry.CurrentValues;
var databaseValues = entry.GetDatabaseValues();
//databaseValues == null说明数据已被删除
if (databaseValues != null)
{
foreach (var property in properties == null
|| properties.Length == 0 ? proposedValues.Properties
: proposedValues.Properties.Where(x => properties.Contains(x.Name)))
{
var proposedValue = proposedValues[property];
var databaseValue = databaseValues[property];
}
affectedRows++;
entry.OriginalValues.SetValues(databaseValues);
}
}
if (affectedRows == 0) { }
else
DbContext.SaveChanges();
}
}
}
/// <summary>
/// 注意List生成的table的列顺序必须要和数据库表的列顺序一致
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entities"></param>
public virtual void BulkInsert(IEnumerable<TEntity> entities, bool setOutputIdentity = false)
{
// EFContext.Model.FindEntityType("").Relational()
//Pomelo.EntityFrameworkCore.MySql
try
{
// EFContext.BulkInsert(entities.ToList());
}
catch (DbUpdateException ex)
{
throw (ex.InnerException as Exception ?? ex);
}
// BulkInsert(entities.ToDataTable(), typeof(T).GetEntityTableName(), null);
}
public virtual int SaveChanges()
{
return EFContext.SaveChanges();
}
public virtual Task<int> SaveChangesAsync()
{
return EFContext.SaveChangesAsync();
}
public virtual int ExecuteSqlCommand(string sql, params SqlParameter[] sqlParameters)
{
return DbContext.Database.ExecuteSqlRaw(sql, sqlParameters);
}
/*
string joinKeys = $"{string.Join(",", keys)}";
string sql = $"DELETE FROM {typeof(OP_WMS_STOREHOUSE_AREA).GetEntityTableName() } where pid in ({joinKeys}) ;" +
$"DELETE FROM {typeof(OP_WMS_STOREHOUSE_GOODSTYPE).GetEntityTableName() } where AREACODE in (select AREACODE from OP_WMS_STOREHOUSE where id in ({joinKeys})) ;";
sql = sql + " ";
repository.ExecuteSqlCommand(sql);
*/
public virtual List<TEntity> FromSql(string sql, params SqlParameter[] sqlParameters)
{
return DBSet.FromSqlRaw(sql, sqlParameters).ToList();
}
/// <summary>
/// 异步执行带有参数的存储过程方法 获取信息集合以及返回空值处理
/// </summary>
/// <param name="db"></param>
/// <param name="sql"></param>
/// <param name="sqlParams"></param>
/// <returns></returns>
public async Task<List<Dictionary<string, object>>> ExecSpAsync( string sql, SqlParameter[] sqlParams)
{
var connection = DbContext.Database.GetDbConnection();
using (var cmd = connection.CreateCommand())
{
await DbContext.Database.OpenConnectionAsync();
cmd.CommandText = sql;
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddRange(sqlParams);
var dr = await cmd.ExecuteReaderAsync();
var columnSchema = dr.GetColumnSchema();
var data = new List<Dictionary<string, object>>();
while (await dr.ReadAsync())
{
var item = new Dictionary<string, object>();
foreach (var kv in columnSchema)
{
if (kv.ColumnOrdinal.HasValue)
{
var itemVal = dr.GetValue(kv.ColumnOrdinal.Value);
item.Add(kv.ColumnName, itemVal.GetType() != typeof(DBNull) ? itemVal : "");
}
}
data.Add(item);
}
dr.Dispose();
return data;
}
}
/*//查 获取信息
string userId =888886868886;
//多个参数多表组合值
SqlParameter[] Param =
{
new SqlParameter("@UserId", System.Data.SqlDbType.VarChar)
};
if (string.IsNullOrEmpty(userId))
{ Param[0].Value = DBNull.Value; }
else
{ Param[0].Value = userId; }
var userdata = await _context.ExecSpAsync("SP_GetList", Param);
*/
public List<Dictionary<string, object>> ExecSp(string sql, SqlParameter[] sqlParams)
{
var connection = DbContext.Database.GetDbConnection();
using (var cmd = connection.CreateCommand())
{
DbContext.Database.OpenConnectionAsync();
cmd.CommandText = sql;
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddRange(sqlParams);
var dr = cmd.ExecuteReader();
var columnSchema = dr.GetColumnSchema();
var data = new List<Dictionary<string, object>>();
while (dr.Read())
{
var item = new Dictionary<string, object>();
foreach (var kv in columnSchema)
{
if (kv.ColumnOrdinal.HasValue)
{
var itemVal = dr.GetValue(kv.ColumnOrdinal.Value);
item.Add(kv.ColumnName, itemVal.GetType() != typeof(DBNull) ? itemVal : "");
}
}
data.Add(item);
}
if (cmd.Parameters != null)
{
var param = new Dictionary<string, object>();
foreach (SqlParameter item in cmd.Parameters)
{
param.Add(item.ParameterName, item.Value.ToString());
}
}
dr.Dispose();
return data;
}
}
/// <summary>
/// 异步执行带有参数的查询语句 获取信息集合以及返回空值处理
/// </summary>
/// <param name="db"></param>
/// <param name="sql"></param>
/// <param name="sqlParams"></param>
/// <returns></returns>
public async Task<List<Dictionary<string, object>>> ExecAsync(string sql)
{
var connection = DbContext.Database.GetDbConnection();
using (var cmd = connection.CreateCommand())
{
await DbContext.Database.OpenConnectionAsync();
cmd.CommandText = sql;
cmd.CommandType = System.Data.CommandType.Text;
//cmd.Parameters.AddRange(sqlParams);
var dr = await cmd.ExecuteReaderAsync();
var columnSchema = dr.GetColumnSchema();
var data = new List<Dictionary<string, object>>();
while (await dr.ReadAsync())
{
var item = new Dictionary<string, object>();
foreach (var kv in columnSchema)
{
if (kv.ColumnOrdinal.HasValue)
{
var itemVal = dr.GetValue(kv.ColumnOrdinal.Value);
item.Add(kv.ColumnName, itemVal.GetType() != typeof(DBNull) ? itemVal : "");
}
}
data.Add(item);
}
dr.Dispose();
return data;
}
}
public List<Dictionary<string, object>> Exec(string sql, SqlParameter[] sqlParams)
{
var connection = DbContext.Database.GetDbConnection();
using (var cmd = connection.CreateCommand())
{
DbContext.Database.OpenConnection();
cmd.CommandText = sql;
cmd.CommandType = System.Data.CommandType.Text;
if(sqlParams!=null && sqlParams.Length>0)
cmd.Parameters.AddRange(sqlParams);
var dr = cmd.ExecuteReader();
var columnSchema = dr.GetColumnSchema();
var data = new List<Dictionary<string, object>>();
while ( dr.Read())
{
var item = new Dictionary<string, object>();
foreach (var kv in columnSchema)
{
if (kv.ColumnOrdinal.HasValue)
{
var itemVal = dr.GetValue(kv.ColumnOrdinal.Value);
item.Add(kv.ColumnName, itemVal.GetType() != typeof(DBNull) ? itemVal : "");
}
}
data.Add(item);
}
dr.Dispose();
return data;
}
}
/// <summary>
/// 异步执行带有参数的存储过程方法 增删改操作以及返回带有输出的参数
/// </summary>
/// <param name="db"></param>
/// <param name="sql"></param>
/// <param name="sqlParams"></param>
/// <returns></returns>
public async Task<int> ExecuteNonQueryAsync( string sql, SqlParameter[] sqlParams)
{
int numint;
var connection = DbContext.Database.GetDbConnection();
using (var cmd = connection.CreateCommand())
{
await DbContext.Database.OpenConnectionAsync();
cmd.CommandText = sql;
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddRange(sqlParams);
numint = await cmd.ExecuteNonQueryAsync();
}
return numint;
}
/*//增删改调用例子
*
* SqlParameter[] Param =
{
new SqlParameter("@MobilePhone", System.Data.SqlDbType.VarChar),
new SqlParameter("@PayPrice", System.Data.SqlDbType.VarChar),
new SqlParameter("@rt_code", System.Data.SqlDbType.NVarChar, 20),
new SqlParameter("@rt_msg", System.Data.SqlDbType.NVarChar, 200), //输出一定要定义字符类型长度 以免报错
};
if (string.IsNullOrEmpty(strMobilePhone))
{ Param[0].Value = DBNull.Value; }
else
{ Param[0].Value = strMobilePhone; }
Param[1].Value = strPayPrice;
if (string.IsNullOrEmpty(strParkUserId))
{ Param[2].Value = DBNull.Value; }
else
{ Param[2].Value = strParkUserId; }
Param[2].Direction = ParameterDirection.Output;
Param[3].Direction = ParameterDirection.Output;
int numdata = await _dbcontext.ExecuteNonQueryAsync("SP_Pay", Param);
string rtcode = Param[2].Value.ToString();
string rtmessage = Param[3].Value.ToString();
if (numdata < 0)
{
return AsResult.Error(Convert.ToInt32(rtcode), rtmessage);
}
*/
public string GetBillno(string OPLBNAME, string RULEBLNO,Guid CompanyId) {
return "";
}
/// <summary>
/// 执行sql
/// 使用方式 FormattableString sql=$"select * from xx where name ={xx} and pwd={xx1} "
/// FromSqlInterpolated内部处理sql注入的问题直接在{xx}写对应的值即可
/// 注意sql必须 select * 返回所有TEntity字段
/// </summary>
/// <param name="formattableString"></param>
/// <returns></returns>
public virtual IQueryable<TEntity> FromSqlInterpolated([NotNull] FormattableString sql)
{
//DBSet.FromSqlInterpolated(sql).Select(x => new { x,xxx}).ToList();
return DBSet.FromSqlInterpolated(sql);
}
}
}