6 major server modules (PdkFriendServer/GlobalSever/ServerCore/GameModule/GameNetModule) + game logic (GameFix/GameDAL/ServerData) + network layer (NetWorkMessage) + data layer (ObjectModel) + utilities (MrWu/Core/Config/CloudAPI/dll) + adapters (zyxAdapter/base) .NET 8.0 C# solution, 16 projects, 958 source files
615 lines
25 KiB
C#
615 lines
25 KiB
C#
using System.Data;
|
|
using System.Linq;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections;
|
|
using System.Reflection;
|
|
using System.Collections.ObjectModel;
|
|
using System.Data.SqlClient;
|
|
using System.Threading.Tasks;
|
|
using System.Collections.Concurrent;
|
|
using MrWu.Debug;
|
|
|
|
/// <summary>
|
|
/// ADOExtensions
|
|
/// </summary>
|
|
public static partial class ADOExtensions {
|
|
|
|
|
|
static MethodInfo GetColumeValueMethod { get; }
|
|
|
|
|
|
#region DataTable Extensions
|
|
|
|
/// <summary>
|
|
/// TryGetValue from DataTable
|
|
/// </summary>
|
|
/// <typeparam name="TValue"></typeparam>
|
|
/// <param name="table"></param>
|
|
/// <param name="columnName"></param>
|
|
/// <param name="value"></param>
|
|
/// <param name="rowNumber"></param>
|
|
/// <returns></returns>
|
|
public static bool TryGetValue<TValue>(this DataTable table, string columnName, out TValue value, int rowNumber = 0) {
|
|
if (table.Rows.Count > rowNumber) {
|
|
value = table.Rows[rowNumber].GetValue<TValue>(columnName);
|
|
return true;
|
|
}
|
|
value = default(TValue);
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// GetValue from DataTable
|
|
/// </summary>
|
|
/// <typeparam name="TValue"></typeparam>
|
|
/// <param name="table"></param>
|
|
/// <param name="columnName"></param>
|
|
/// <param name="rowNumber"></param>
|
|
/// <param name="defaultValue"></param>
|
|
/// <returns></returns>
|
|
public static TValue GetValue<TValue>(this DataTable table, string columnName, int rowNumber = 0, TValue defaultValue = default(TValue)) {
|
|
return table.TryGetValue<TValue>(columnName, out var outValue, rowNumber) ? outValue : defaultValue;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Select
|
|
/// </summary>
|
|
/// <typeparam name="TObject"></typeparam>
|
|
/// <param name="table"></param>
|
|
/// <param name="selector"></param>
|
|
/// <returns></returns>
|
|
public static IEnumerable<TObject> Select<TObject>(this DataTable table, Func<DataRow, TObject> selector) {
|
|
foreach (DataRow row in table.Rows) {
|
|
yield return selector.Invoke(row);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// ToObjects
|
|
/// </summary>
|
|
/// <typeparam name="TObject"></typeparam>
|
|
/// <param name="table"></param>
|
|
/// <returns></returns>
|
|
public static IEnumerable<TObject> ToObjects<TObject>(this DataTable table) where TObject : new() {
|
|
foreach (DataRow row in table.Rows) {
|
|
yield return row.ToObject<TObject>();
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region DataRow Extensions
|
|
|
|
#region 泛型方法
|
|
|
|
#region 单列解析方法
|
|
|
|
/// <summary>
|
|
/// GetValue
|
|
/// </summary>
|
|
/// <typeparam name="TValue"></typeparam>
|
|
/// <param name="row">DataRow</param>
|
|
/// <param name="column">DataColumn</param>
|
|
/// <returns></returns>
|
|
public static TValue GetColumeValue<TValue>(this DataRow row, DataColumn column) {
|
|
var columnValue = row[column];
|
|
if (columnValue is TValue value) {
|
|
return value;
|
|
}
|
|
if (columnValue is DBNull && column.AllowDBNull) {
|
|
return default(TValue);
|
|
}
|
|
throw new ArgumentOutOfRangeException($"无效的泛型类型,列名:{column.ColumnName},泛型类型为:{typeof(TValue)},数据列类型为:{GetColumnDataType(column)}");
|
|
}
|
|
|
|
/// <summary>
|
|
/// GetValue from DataRow
|
|
/// </summary>
|
|
/// <typeparam name="TValue"></typeparam>
|
|
/// <param name="row"></param>
|
|
/// <param name="columnName"></param>
|
|
/// <returns></returns>
|
|
public static TValue GetValue<TValue>(this DataRow row, string columnName) {
|
|
if (row.TryGetColumn(columnName, out var column)) {
|
|
return row.GetColumeValue<TValue>(column);
|
|
}
|
|
throw new ArgumentOutOfRangeException("未找到字段:" + columnName);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 整行解析方法
|
|
|
|
static ConcurrentDictionary<Type, ICollection<MemberInfo>> memberInfoOfType = new ConcurrentDictionary<Type, ICollection<MemberInfo>>();
|
|
|
|
/// <summary>
|
|
/// ToObject from DataRow
|
|
/// </summary>
|
|
/// <typeparam name="TObject"></typeparam>
|
|
/// <param name="row"></param>
|
|
/// <returns></returns>
|
|
public static TObject ToObject<TObject>(this DataRow row) where TObject : new() {
|
|
var type = typeof(TObject);
|
|
var objectMembers = memberInfoOfType.GetOrAdd(type, t => {
|
|
var collection = new Collection<MemberInfo>();
|
|
foreach (var item in type.GetProperties().Where(p => p.CanRead && p.CanWrite && p.GetIndexParameters().Length == 0)) {
|
|
collection.Add(item);
|
|
}
|
|
foreach (var item in type.GetFields().Where(p => !p.IsInitOnly && p.IsPublic)) {
|
|
collection.Add(item);
|
|
}
|
|
return collection;
|
|
});
|
|
var obj = new TObject();
|
|
foreach (var item in objectMembers) {
|
|
if (item is FieldInfo fieldInfo) {
|
|
row.TrySetMemberValue(obj, fieldInfo.Name, fieldInfo.FieldType, fieldInfo.SetValue);
|
|
} else if (item is PropertyInfo propertyInfo) {
|
|
row.TrySetMemberValue(obj, propertyInfo.Name, propertyInfo.PropertyType, propertyInfo.SetValue);
|
|
}
|
|
}
|
|
return obj;
|
|
}
|
|
|
|
static void TrySetMemberValue(this DataRow row, object parent, string memberName, Type memberType, Action<object, object> valueSetMethod) {
|
|
var column = row.Table.Columns[memberName];
|
|
if (column != null) {
|
|
var value = row[column];
|
|
try {
|
|
if (value != null && !(value is DBNull)) {
|
|
var sourceType = value.GetType();
|
|
if (memberType.IsEnum) {
|
|
value = Enum.ToObject(memberType, value);
|
|
} else if (memberType.IsGenericType && memberType.GetGenericTypeDefinition() == typeof(Nullable<>)) {
|
|
//目标类型为 Nullable<>,无需转换,可直接赋值
|
|
} else if (!sourceType.IsAssignableFrom(memberType) && value is IConvertible convert) {
|
|
value = convert.ToType(memberType, null);
|
|
}
|
|
valueSetMethod.Invoke(parent, value);
|
|
}
|
|
} catch (Exception ex) {
|
|
throw new ArgumentException($"TrySetMemberValue 数据类型定义错误, 定义类型与数据库类型不一致, 成员名:{memberName}, 当前泛型参数类型为: {memberType}, 实际数据类型:{ GetColumnDataType(row.Table.Columns[memberName])}, data: {value}", ex);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// ToDictionary from DataRow
|
|
/// </summary>
|
|
/// <param name="row"></param>
|
|
/// <returns></returns>
|
|
public static IDictionary<string, object> ToDictionary(this DataRow row) {
|
|
var columns = row.Table.Columns;
|
|
var dict = new Dictionary<string, object>();
|
|
foreach (DataColumn column in columns) {
|
|
var value = row.GetValue(column);
|
|
dict.Add(column.ColumnName, value);
|
|
}
|
|
return dict;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region 非泛型方法
|
|
|
|
/// <summary>
|
|
/// TryGetValue
|
|
/// </summary>
|
|
/// <param name="row"></param>
|
|
/// <param name="columnName"></param>
|
|
/// <param name="value"></param>
|
|
/// <returns></returns>
|
|
public static bool TryGetValue(this DataRow row, string columnName, out object value) {
|
|
if (row.TryGetColumn(columnName, out var column)) {
|
|
value = row.GetValue(column);
|
|
return true;
|
|
}
|
|
value = null;
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="row"></param>
|
|
/// <param name="column"></param>
|
|
/// <returns></returns>
|
|
public static object GetValue(this DataRow row, DataColumn column) {
|
|
var columnType = GetColumnDataType(column);
|
|
var value = row[column];
|
|
return value is DBNull ? null : value;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="column"></param>
|
|
/// <returns></returns>
|
|
public static Type GetColumnDataType(this DataColumn column) => column.AllowDBNull && column.DataType.IsValueType ? typeof(Nullable<>).MakeGenericType(column.DataType) : column.DataType;
|
|
|
|
/// <summary>
|
|
/// TryGetColumn from DataRow
|
|
/// </summary>
|
|
/// <param name="row"></param>
|
|
/// <param name="columnName"></param>
|
|
/// <param name="column"></param>
|
|
/// <returns></returns>
|
|
public static bool TryGetColumn(this DataRow row, string columnName, out DataColumn column) {
|
|
column = row.Table.Columns[columnName];
|
|
return column != null;
|
|
}
|
|
|
|
internal static int SQLValue(this bool value) => value ? 1 : 0;
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region SQL命令扩展
|
|
|
|
#region 构造与内部成员
|
|
|
|
private static string connectionString { get; }
|
|
|
|
|
|
#endregion
|
|
|
|
#region 单结果集查询
|
|
|
|
public static DataTable ExecuteTable(this dbbase db, string sqlText, params SqlParameter[] parameters) {
|
|
return db.ExecuteCommand(sqlText, cmd => cmd.FillTable(), parameters);
|
|
}
|
|
|
|
public static DataTable ExecuteTable(this dbbase db, string sqlText, CommandType type, params SqlParameter[] parameters) {
|
|
return db.ExecuteCommand(sqlText, cmd => cmd.FillTable(), type, parameters);
|
|
}
|
|
|
|
public static Task<DataTable> ExecuteTableAsync(this dbbase db, string sqlText, params SqlParameter[] parameters) {
|
|
return db.ExecuteCommandAsync(sqlText, async cmd => await cmd.FillTableAsync(), parameters);
|
|
}
|
|
|
|
public static Task<DataTable> ExecuteTableAsync(this dbbase db, string sqlText, CommandType type, params SqlParameter[] parameters) {
|
|
return db.ExecuteCommandAsync(sqlText, async cmd => await cmd.FillTableAsync(), type, parameters);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 多结果集查询
|
|
|
|
public static DataTable[] ExecuteTables(this dbbase db, string sqlText, params SqlParameter[] parameters) {
|
|
return db.ExecuteCommand(sqlText, cmd => cmd.FillTables(), parameters);
|
|
}
|
|
|
|
public static DataTable[] ExecuteTables(this dbbase db, string sqlText, CommandType type, params SqlParameter[] parameters) {
|
|
return db.ExecuteCommand(sqlText, cmd => cmd.FillTables(), type, parameters);
|
|
}
|
|
|
|
public static Task<DataTable[]> ExecuteTablesAsync(this dbbase db, string sqlText, params SqlParameter[] parameters) {
|
|
return db.ExecuteCommandAsync(sqlText, async cmd => await cmd.FillTablesAsync(), parameters);
|
|
}
|
|
|
|
public static Task<DataTable[]> ExecuteTablesAsync(this dbbase db, string sqlText, CommandType type, params SqlParameter[] parameters) {
|
|
return db.ExecuteCommandAsync(sqlText, async cmd => await cmd.FillTablesAsync(), type, parameters);
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
#region 执行无结果集SQL
|
|
|
|
public static int ExecuteNonQuery(this dbbase db, string sqlText, params SqlParameter[] parameters) {
|
|
return db.ExecuteCommand(sqlText, cmd => cmd.ExecuteNonQuery(), parameters);
|
|
}
|
|
|
|
public static int ExecuteNonQuery(this dbbase db, string sqlText, CommandType type, params SqlParameter[] parameters) {
|
|
return db.ExecuteCommand(sqlText, cmd => cmd.ExecuteNonQuery(), type, parameters);
|
|
}
|
|
|
|
public static Task<int> ExecuteNonQueryAsync(this dbbase db, string sqlText, params SqlParameter[] parameters) {
|
|
return db.ExecuteCommandAsync(sqlText, cmd => cmd.ExecuteNonQueryAsync(), parameters);
|
|
}
|
|
|
|
public static Task<int> ExecuteNonQueryAsync(this dbbase db, string sqlText, CommandType type, params SqlParameter[] parameters) {
|
|
return db.ExecuteCommandAsync(sqlText, cmd => cmd.ExecuteNonQueryAsync(), type, parameters);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 执行首行首列查询
|
|
|
|
public static object ExecuteScalar(this dbbase db, string sqlText, params SqlParameter[] parameters) {
|
|
return db.ExecuteCommand(sqlText, cmd => cmd.ExecuteScalar(), parameters);
|
|
}
|
|
|
|
public static object ExecuteScalar(this dbbase db, string sqlText, CommandType type, params SqlParameter[] parameters) {
|
|
return db.ExecuteCommand(sqlText, cmd => cmd.ExecuteScalar(), type, parameters);
|
|
}
|
|
|
|
public static Task<object> ExecuteScalarAsync(this dbbase db, string sqlText, params SqlParameter[] parameters) {
|
|
return db.ExecuteCommandAsync(sqlText, cmd => cmd.ExecuteScalarAsync(), parameters);
|
|
}
|
|
|
|
public static Task<object> ExecuteScalarAsync(this dbbase db, string sqlText, CommandType type, params SqlParameter[] parameters) {
|
|
return db.ExecuteCommandAsync(sqlText, cmd => cmd.ExecuteScalarAsync(), type, parameters);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 泛型方法
|
|
|
|
#region 单表实体集查询
|
|
|
|
public static IEnumerable<TResult> ExecuteEntities<TResult>(this dbbase db, string sqlText, Func<DataRow, TResult> resultSelector, params SqlParameter[] parameters) {
|
|
return db.ExecuteCommand(sqlText, cmd => cmd.FillTable().Select(p => resultSelector.Invoke(p)), parameters);
|
|
}
|
|
|
|
public static IEnumerable<TResult> ExecuteEntities<TResult>(this dbbase db, string sqlText, Func<DataRow, TResult> resultSelector, CommandType type, params SqlParameter[] parameters) {
|
|
return db.ExecuteCommand(sqlText, cmd => cmd.FillTable().Select(p => resultSelector.Invoke(p)), type, parameters);
|
|
}
|
|
|
|
public static Task<IEnumerable<TResult>> ExecuteEntitiesAsync<TResult>(this dbbase db, string sqlText, Func<DataRow, TResult> resultSelector, params SqlParameter[] parameters) {
|
|
return db.ExecuteCommandAsync(sqlText, async cmd => (await cmd.FillTableAsync()).Select(p => resultSelector.Invoke(p)), parameters);
|
|
}
|
|
|
|
public static Task<IEnumerable<TResult>> ExecuteEntitiesAsync<TResult>(this dbbase db, string sqlText, Func<DataRow, TResult> resultSelector, CommandType type, params SqlParameter[] parameters) {
|
|
return db.ExecuteCommandAsync(sqlText, async cmd => (await cmd.FillTableAsync()).Select(p => resultSelector.Invoke(p)), type, parameters);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 多表实体集查询
|
|
|
|
public static TResult ExecuteEntities2<TResult>(this dbbase db, string sqlText, Func<DataTable[], TResult> resultSelector, params SqlParameter[] parameters) {
|
|
return db.ExecuteCommand(sqlText, cmd => resultSelector.Invoke(cmd.FillTables()), parameters);
|
|
}
|
|
|
|
public static TResult ExecuteEntities2<TResult>(this dbbase db, string sqlText, Func<DataTable[], TResult> resultSelector, CommandType type, params SqlParameter[] parameters) {
|
|
return db.ExecuteCommand(sqlText, cmd => resultSelector.Invoke(cmd.FillTables()), type, parameters);
|
|
}
|
|
|
|
public static Task<TResult> ExecuteEntities2Async<TResult>(this dbbase db, string sqlText, Func<DataTable[], TResult> resultSelector, params SqlParameter[] parameters) {
|
|
return db.ExecuteCommandAsync(sqlText, async cmd => resultSelector.Invoke(await cmd.FillTablesAsync()), parameters);
|
|
}
|
|
|
|
public static Task<TResult> ExecuteEntities2Async<TResult>(this dbbase db, string sqlText, Func<DataTable[], TResult> resultSelector, CommandType type, params SqlParameter[] parameters) {
|
|
return db.ExecuteCommandAsync(sqlText, async cmd => resultSelector.Invoke(await cmd.FillTablesAsync()), type, parameters);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region
|
|
|
|
public static TResult ExecuteCommand<TResult>(this dbbase db, string sqlText, Func<SqlCommand, TResult> resultSelector, params SqlParameter[] parameters) {
|
|
return db.ExecuteCommand(sqlText, resultSelector, CommandType.Text, parameters);
|
|
}
|
|
|
|
public static TResult ExecuteCommand<TResult>(this dbbase db, string sqlText, Func<SqlCommand, TResult> resultSelector, CommandType type, params SqlParameter[] parameters) {
|
|
using (SqlConnection conn = new SqlConnection(connectionString)) {
|
|
conn.Open();
|
|
conn.ChangeDatabase(GetDataBaseName(db));
|
|
using (var cmd = conn.CreateCommand()) {
|
|
cmd.CommandText = sqlText;
|
|
cmd.CommandType = type;
|
|
if (parameters != null && parameters.Length > 0) {
|
|
cmd.Parameters.AddRange(parameters);
|
|
}
|
|
return resultSelector.Invoke(cmd);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static Task<TResult> ExecuteCommandAsync<TResult>(this dbbase db, string sqlText, Func<SqlCommand, Task<TResult>> resultSelector, params SqlParameter[] parameters) {
|
|
return db.ExecuteCommandAsync(sqlText, resultSelector, CommandType.Text, parameters);
|
|
}
|
|
|
|
public static async Task<TResult> ExecuteCommandAsync<TResult>(this dbbase db, string sqlText, Func<SqlCommand, Task<TResult>> resultSelector, CommandType type, params SqlParameter[] parameters) {
|
|
using (SqlConnection conn = new SqlConnection(connectionString)) {
|
|
await conn.OpenAsync();
|
|
conn.ChangeDatabase(GetDataBaseName(db));
|
|
using (var cmd = conn.CreateCommand()) {
|
|
cmd.CommandText = sqlText;
|
|
cmd.CommandType = type;
|
|
if (parameters != null && parameters.Length > 0) {
|
|
cmd.Parameters.AddRange(parameters);
|
|
}
|
|
return await resultSelector.Invoke(cmd);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region 事务
|
|
|
|
public static TResult ExecuteTransaction<TResult>(this dbbase db, Func<SqlTransaction, TResult> transactionAction) {
|
|
return db.ExecuteTransaction(true, transactionAction);
|
|
}
|
|
|
|
public static TResult ExecuteTransaction<TResult>(this dbbase db, bool throwIfException, Func<SqlTransaction, TResult> transactionAction) {
|
|
var result = default(TResult);
|
|
using (var conn = new SqlConnection(connectionString)) {
|
|
conn.Open();
|
|
conn.ChangeDatabase(GetDataBaseName(db));
|
|
using (var transaction = conn.BeginTransaction()) {
|
|
try {
|
|
result = transactionAction.Invoke(transaction);
|
|
transaction.Commit();
|
|
} catch (Exception ex) {
|
|
Debug.Error("ExecuteTransaction " + ex);
|
|
transaction.SafeRollback();
|
|
if (throwIfException) {
|
|
throw ex;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static Task<TResult> ExecuteTransactionAsync<TResult>(this dbbase db, Func<SqlTransaction, Task<TResult>> transactionAction) {
|
|
return db.ExecuteTransactionAsync(true, transactionAction);
|
|
}
|
|
|
|
public static async Task<TResult> ExecuteTransactionAsync<TResult>(this dbbase db, bool throwIfException, Func<SqlTransaction, Task<TResult>> transactionAction) {
|
|
var result = default(TResult);
|
|
using (var conn = new SqlConnection(connectionString)) {
|
|
await conn.OpenAsync();
|
|
conn.ChangeDatabase(GetDataBaseName(db));
|
|
using (var transaction = conn.BeginTransaction()) {
|
|
try {
|
|
result = await transactionAction.Invoke(transaction);
|
|
transaction.Commit();
|
|
} catch (Exception ex) {
|
|
Debug.Error("ExecuteTransaction " + ex);
|
|
transaction.SafeRollback();
|
|
if (throwIfException) {
|
|
throw ex;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="transaction"></param>
|
|
/// <param name="sqlText"></param>
|
|
/// <param name="parameters"></param>
|
|
/// <returns></returns>
|
|
public static TResult ExecuteQuery<TResult>(this SqlTransaction transaction, string sqlText, Func<SqlCommand, TResult> resultSelector, params SqlParameter[] parameters) {
|
|
return transaction.ExecuteQuery(sqlText, resultSelector, CommandType.Text, parameters);
|
|
}
|
|
|
|
public static TResult ExecuteQuery<TResult>(this SqlTransaction transaction, string sqlText, Func<SqlCommand, TResult> resultSelector, CommandType type, params SqlParameter[] parameters) {
|
|
using (var cmd = new SqlCommand(sqlText, transaction.Connection, transaction) { CommandType = type }) {
|
|
if (parameters != null && parameters.Length > 0) {
|
|
cmd.Parameters.AddRange(parameters);
|
|
}
|
|
var result = resultSelector.Invoke(cmd);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
public static int ExecuteNonQuery(this SqlTransaction transaction, string sqlText, params SqlParameter[] parameters) {
|
|
return transaction.ExecuteNonQuery(sqlText, CommandType.Text, parameters);
|
|
}
|
|
|
|
public static int ExecuteNonQuery(this SqlTransaction transaction, string sqlText, CommandType type, params SqlParameter[] parameters) {
|
|
return transaction.ExecuteQuery(sqlText, cmd => cmd.ExecuteNonQuery(), type, parameters);
|
|
}
|
|
|
|
public static Task<int> ExecuteNonQueryAsync(this SqlTransaction transaction, string sqlText, params SqlParameter[] parameters) {
|
|
return transaction.ExecuteNonQueryAsync(sqlText, CommandType.Text, parameters);
|
|
}
|
|
|
|
public static Task<int> ExecuteNonQueryAsync(this SqlTransaction transaction, string sqlText, CommandType type, params SqlParameter[] parameters) {
|
|
return transaction.ExecuteQuery(sqlText, cmd => cmd.ExecuteNonQueryAsync(), type, parameters);
|
|
}
|
|
|
|
public static object ExecuteScalar(this SqlTransaction transaction, string sqlText, params SqlParameter[] parameters) {
|
|
return transaction.ExecuteScalar(sqlText, CommandType.Text, parameters);
|
|
}
|
|
|
|
public static object ExecuteScalar(this SqlTransaction transaction, string sqlText, CommandType type, params SqlParameter[] parameters) {
|
|
return transaction.ExecuteQuery(sqlText, cmd => cmd.ExecuteScalar(), type, parameters);
|
|
}
|
|
|
|
public static Task<object> ExecuteScalarAsync(this SqlTransaction transaction, string sqlText, params SqlParameter[] parameters) {
|
|
return transaction.ExecuteScalarAsync(sqlText, CommandType.Text, parameters);
|
|
}
|
|
|
|
public static Task<object> ExecuteScalarAsync(this SqlTransaction transaction, string sqlText, CommandType type, params SqlParameter[] parameters) {
|
|
return transaction.ExecuteQuery(sqlText, cmd => cmd.ExecuteScalarAsync(), type, parameters);
|
|
}
|
|
|
|
public static void SafeRollback(this SqlTransaction transaction) {
|
|
try {
|
|
transaction.Rollback();
|
|
} catch (Exception ex) {
|
|
Debug.Error("SafeRollback:" + ex);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Common
|
|
|
|
private static string GetDataBaseName(dbbase db) {
|
|
switch (db) {
|
|
case dbbase.gamedb:
|
|
return "jnxdgame";
|
|
case dbbase.game2018:
|
|
return "game2018";
|
|
default:
|
|
throw new NotSupportedException(nameof(db));
|
|
}
|
|
}
|
|
|
|
public static DataTable FillTable(this SqlCommand cmd) {
|
|
return cmd.FillTables().FirstOrDefault() ?? new DataTable();
|
|
}
|
|
|
|
public static DataTable[] FillTables(this SqlCommand cmd) {
|
|
using (var adapter = new SqlDataAdapter(cmd)) {
|
|
using (var dataSet = new DataSet()) {
|
|
adapter.Fill(dataSet);
|
|
var tabs = new DataTable[dataSet.Tables.Count];
|
|
for (int i = 0; i < dataSet.Tables.Count; i++) {
|
|
tabs[i] = dataSet.Tables[i];
|
|
}
|
|
return tabs;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static async Task<DataTable> FillTableAsync(this SqlCommand cmd) {
|
|
using (var reader = await cmd.ExecuteReaderAsync()) {
|
|
return await reader.FillTableInternal();
|
|
}
|
|
}
|
|
|
|
public static async Task<DataTable[]> FillTablesAsync(this SqlCommand cmd) {
|
|
using (var reader = await cmd.ExecuteReaderAsync()) {
|
|
var tables = new Collection<DataTable>();
|
|
do {
|
|
var datatable = await reader.FillTableInternal();
|
|
if (datatable != null) {
|
|
tables.Add(datatable);
|
|
}
|
|
} while (await reader.NextResultAsync());
|
|
return tables.ToArray();
|
|
}
|
|
}
|
|
|
|
static async Task<DataTable> FillTableInternal(this SqlDataReader reader) {
|
|
var datatable = new DataTable();
|
|
if (reader.FieldCount > 0) {
|
|
datatable.Columns.AddRange(Enumerable.Range(0, reader.FieldCount)
|
|
.Select(i => new DataColumn(reader.GetName(i), reader.GetFieldType(i)))
|
|
.ToArray());
|
|
|
|
///添加行数据
|
|
while (await reader.ReadAsync()) {
|
|
var myDataRow = datatable.NewRow();
|
|
for (int i = 0; i < reader.FieldCount; i++) {
|
|
myDataRow[i] = reader[i];
|
|
}
|
|
datatable.Rows.Add(myDataRow);
|
|
}
|
|
}
|
|
return datatable;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
}
|