一.数据库和技术应用
数据库orcle,可扩展其他数据库
应用技术 C# Reflection,Reflection.Emit, Attribute
二.数据库连接代码,这段代码是抄的csdn某位仁兄,具体记不得了
代码:DataReader扩展
using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;
using System.Reflection.Emit;
using DBExtensions;
namespace DAL
{
/// <summary>
/// DataReader Extensions
/// </summary>
public static class DataReaderExtensions
{
#region Static Readonly Fields
private static readonly MethodInfo DataRecord_ItemGetter_String =
typeof(IDataRecord).GetMethod("get_Item", new Type[] { typeof(string) });
private static readonly MethodInfo DataRecord_ItemGetter_Int =
typeof(IDataRecord).GetMethod("get_Item", new Type[] { typeof(int) });
private static readonly MethodInfo DataRecord_GetOrdinal =
typeof(IDataRecord).GetMethod("GetOrdinal");
private static readonly MethodInfo DataReader_Read =
typeof(IDataReader).GetMethod("Read");
private static readonly MethodInfo Convert_IsDBNull =
typeof(Convert).GetMethod("IsDBNull");
private static readonly MethodInfo DataRecord_GetDateTime =
typeof(IDataRecord).GetMethod("GetDateTime");
private static readonly MethodInfo DataRecord_GetDecimal =
typeof(IDataRecord).GetMethod("GetDecimal");
private static readonly MethodInfo DataRecord_GetDouble =
typeof(IDataRecord).GetMethod("GetDouble");
private static readonly MethodInfo DataRecord_GetFloat =
typeof(IDataRecord).GetMethod("GetFloat");
private static readonly MethodInfo DataRecord_GetInt32 =
typeof(IDataRecord).GetMethod("GetInt32");
private static readonly MethodInfo DataRecord_GetInt64 =
typeof(IDataRecord).GetMethod("GetInt64");
private static readonly MethodInfo DataRecord_GetString =
typeof(IDataRecord).GetMethod("GetString");
private static readonly MethodInfo DataRecord_IsDBNull =
typeof(IDataRecord).GetMethod("IsDBNull");
#endregion
#region Public Static Methods
/// <summary>
/// 把结果集流转换成数据实体列表
/// </summary>
/// <typeparam name="T">数据实体类型</typeparam>
/// <param name="reader">结果集流</param>
/// <returns>数据实体列表</returns>
public static List<T> Select<T>(this IDataReader reader)
where T : class, new()
{
if (reader == null)
throw new ArgumentNullException("reader");
return EntityConverter<T>.Select(reader);
}
/// <summary>
/// 把结果集流转换成数据实体序列(延迟)
/// </summary>
/// <typeparam name="T">数据实体类型</typeparam>
/// <param name="reader">结果集流</param>
/// <returns>数据实体序列(延迟)</returns>
public static IEnumerable<T> SelectLazy<T>(this IDataReader reader)
where T : class, new()
{
if (reader == null)
throw new ArgumentNullException("reader");
return EntityConverter<T>.SelectDelay(reader);
}
#endregion
#region Class: EntityConverter<T>
/// <summary>
/// 实体转换器
/// </summary>
/// <typeparam name="T">数据实体类型</typeparam>
private class EntityConverter<T>
where T : class, new()
{
#region Struct: DbColumnInfo
private struct DbColumnInfo
{
public readonly string PropertyName;
public readonly string ColumnName;
public readonly Type Type;
public readonly MethodInfo SetMethod;
public readonly bool IsOptional;
public DbColumnInfo(PropertyInfo prop, DbColumnAttribute attr)
{
PropertyName = prop.Name;
ColumnName = attr.ColumnName ?? prop.Name;
Type = prop.PropertyType;
SetMethod = prop.GetSetMethod(false);
IsOptional = attr.IsOptional;
}
}
#endregion
#region Fields
private static Converter<IDataReader, T> dataLoader;
private static Converter<IDataReader, List<T>> batchDataLoader;
#endregion
#region Properties
private static Converter<IDataReader, T> DataLoader
{
get
{
if (dataLoader == null)
dataLoader = CreateDataLoader(new List<DbColumnInfo>(GetProperties()));
return dataLoader;
}
}
private static Converter<IDataReader, List<T>> BatchDataLoader
{
get
{
if (batchDataLoader == null)
batchDataLoader = CreateBatchDataLoader(new List<DbColumnInfo>(GetProperties()));
return batchDataLoader;
}
}
#endregion
#region Init Methods
private static IEnumerable<DbColumnInfo> GetProperties()
{
DbResultAttribute dbResult = Attribute.GetCustomAttribute(typeof(T), typeof(DbResultAttribute), true) as DbResultAttribute;
foreach (var prop in typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public))
{
if (prop.GetIndexParameters().Length > 0)
continue;
var setMethod = prop.GetSetMethod(false);
if (setMethod == null)
continue;
var attr = Attribute.GetCustomAttribute(prop, typeof(DbColumnAttribute), true) as DbColumnAttribute;
if (dbResult != null && dbResult.DefaultAsDbColumn)
if (attr != null && attr.Ignore)
continue;
else
attr = attr ?? new DbColumnAttribute();
else
if (attr == null || attr.Ignore)
continue;
yield return new DbColumnInfo(prop, attr);
}
}
private static Converter<IDataReader, T> CreateDataLoader(List<DbColumnInfo> columnInfoes)
{
DynamicMethod dm = new DynamicMethod(string.Empty, typeof(T),
new Type[] { typeof(IDataReader) }, typeof(EntityConverter<T>));
ILGenerator il = dm.GetILGenerator();
LocalBuilder item = il.DeclareLocal(typeof(T));
// [ int %index% = arg.GetOrdinal(%ColumnName%); ]
LocalBuilder[] colIndices = GetColumnIndices(il, columnInfoes);
// T item = new T { %Property% = ... };
BuildItem(il, columnInfoes, item, colIndices);
// return item;
il.Emit(OpCodes.Ldloc_S, item);
il.Emit(OpCodes.Ret);
return (Converter<IDataReader, T>)dm.CreateDelegate(typeof(Converter<IDataReader, T>));
}
private static Converter<IDataReader, List<T>> CreateBatchDataLoader(List<DbColumnInfo> columnInfoes)
{
DynamicMethod dm = new DynamicMethod(string.Empty, typeof(List<T>),
new Type[] { typeof(IDataReader) }, typeof(EntityConverter<T>));
ILGenerator il = dm.GetILGenerator();
LocalBuilder list = il.DeclareLocal(typeof(List<T>));
LocalBuilder item = il.DeclareLocal(typeof(T));
Label exit = il.DefineLabel();
Label loop = il.DefineLabel();
il.Emit(OpCodes.Newobj, typeof(List<T>).GetConstructor(Type.EmptyTypes));
il.Emit(OpCodes.Stloc_S, list);
LocalBuilder[] colIndices = GetColumnIndices(il, columnInfoes);
il.MarkLabel(loop);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Callvirt, DataReader_Read);
il.Emit(OpCodes.Brfalse, exit);
BuildItem(il, columnInfoes, item, colIndices);
il.Emit(OpCodes.Ldloc_S, list);
il.Emit(OpCodes.Ldloc_S, item);
il.Emit(OpCodes.Callvirt, typeof(List<T>).GetMethod("Add"));
il.Emit(OpCodes.Br, loop);
il.MarkLabel(exit);
il.Emit(OpCodes.Ldloc_S, list);
il.Emit(OpCodes.Ret);
return (Converter<IDataReader, List<T>>)dm.CreateDelegate(typeof(Converter<IDataReader, List<T>>));
}
private static LocalBuilder[] GetColumnIndices(ILGenerator il, List<DbColumnInfo> columnInfoes)
{
LocalBuilder[] colIndices = new LocalBuilder[columnInfoes.Count];
for (int i = 0; i < colIndices.Length; i++)
{
colIndices[i] = il.DeclareLocal(typeof(int));
if (columnInfoes[i].IsOptional)
{
il.BeginExceptionBlock();
}
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldstr, columnInfoes[i].ColumnName);
il.Emit(OpCodes.Callvirt, DataRecord_GetOrdinal);
il.Emit(OpCodes.Stloc_S, colIndices[i]);
if (columnInfoes[i].IsOptional)
{
Label exit = il.DefineLabel();
il.Emit(OpCodes.Leave_S, exit);
il.BeginCatchBlock(typeof(IndexOutOfRangeException));
il.Emit(OpCodes.Pop);
il.Emit(OpCodes.Ldc_I4_M1);
il.Emit(OpCodes.Stloc_S, colIndices[i]);
il.Emit(OpCodes.Leave_S, exit);
il.BeginCatchBlock(typeof(ArgumentException));
il.Emit(OpCodes.Pop);
il.Emit(OpCodes.Ldc_I4_M1);
il.Emit(OpCodes.Stloc_S, colIndices[i]);
il.Emit(OpCodes.Leave_S, exit);
il.EndExceptionBlock();
il.MarkLabel(exit);
}
}
return colIndices;
}
private static void BuildItem(ILGenerator il, List<DbColumnInfo> columnInfoes,
LocalBuilder item, LocalBuilder[] colIndices)
{
il.Emit(OpCodes.Newobj, typeof(T).GetConstructor(Type.EmptyTypes));
il.Emit(OpCodes.Stloc_S, item);
Label skip = new Label();
for (int i = 0; i < colIndices.Length; i++)
{
if (columnInfoes[i].IsOptional)
{
skip = il.DefineLabel();
il.Emit(OpCodes.Ldloc_S, colIndices[i]);
il.Emit(OpCodes.Ldc_I4_M1);
il.Emit(OpCodes.Beq, skip);
}
if (IsCompatibleType(columnInfoes[i].Type, typeof(int)))
{
ReadInt32(il, item, columnInfoes, colIndices, i);
}
else if (IsCompatibleType(columnInfoes[i].Type, typeof(int?)))
{
ReadNullableInt32(il, item, columnInfoes, colIndices, i);
}
else if (IsCompatibleType(columnInfoes[i].Type, typeof(long)))
{
ReadInt64(il, item, columnInfoes, colIndices, i);
}
else if (IsCompatibleType(columnInfoes[i].Type, typeof(long?)))
{
ReadNullableInt64(il, item, columnInfoes, colIndices, i);
}
else if (IsCompatibleType(columnInfoes[i].Type, typeof(decimal)))
{
ReadDecimal(il, item, columnInfoes[i].SetMethod, colIndices[i]);
}
else if (columnInfoes[i].Type == typeof(decimal?))
{
ReadNullableDecimal(il, item, columnInfoes[i].SetMethod, colIndices[i]);
}
else if (columnInfoes[i].Type == typeof(float))
{
ReadFloat(il, item, columnInfoes[i].SetMethod, colIndices[i]);
}
else if (columnInfoes[i].Type == typeof(float?))
{
ReadNullableFloat(il, item, columnInfoes[i].SetMethod, colIndices[i]);
}
else if (columnInfoes[i].Type == typeof(double))
{
ReadDouble(il, item, columnInfoes[i].SetMethod, colIndices[i]);
}
else if (columnInfoes[i].Type == typeof(double?))
{
ReadNullableDouble(il, item, columnInfoes[i].SetMethod, colIndices[i]);
}
else if (columnInfoes[i].Type == typeof(DateTime))
{
ReadDateTime(il, item, columnInfoes[i].SetMethod, colIndices[i]);
}
else if (columnInfoes[i].Type == typeof(DateTime?))
{
ReadNullableDateTime(il, item, columnInfoes[i].SetMethod, colIndices[i]);
}
else
{
ReadObject(il, item, columnInfoes, colIndices, i);
}
if (columnInfoes[i].IsOptional)
{
il.MarkLabel(skip);
}
}
}
private static bool IsCompatibleType(Type t1, Type t2)
{
if (t1 == t2)
return true;
if (t1.IsEnum && Enum.GetUnderlyingType(t1) == t2)
return true;
var u1 = Nullable.GetUnderlyingType(t1);
var u2 = Nullable.GetUnderlyingType(t2);
if (u1 != null && u2 != null)
return IsCompatibleType(u1, u2);
return false;
}
private static void ReadInt32(ILGenerator il, LocalBuilder item,
List<DbColumnInfo> columnInfoes, LocalBuilder[] colIndices, int i)
{
il.Emit(OpCodes.Ldloc_S, item);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldloc_S, colIndices[i]);
il.Emit(OpCodes.Callvirt, DataRecord_GetInt32);
il.Emit(OpCodes.Callvirt, columnInfoes[i].SetMethod);
}
private static void ReadNullableInt32(ILGenerator il, LocalBuilder item,
List<DbColumnInfo> columnInfoes, LocalBuilder[] colIndices, int i)
{
var local = il.DeclareLocal(columnInfoes[i].Type);
Label intNull = il.DefineLabel();
Label intCommon = il.DefineLabel();
il.Emit(OpCodes.Ldloca, local);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldloc_S, colIndices[i]);
il.Emit(OpCodes.Callvirt, DataRecord_IsDBNull);
il.Emit(OpCodes.Brtrue_S, intNull);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldloc_S, colIndices[i]);
il.Emit(OpCodes.Callvirt, DataRecord_GetInt32);
il.Emit(OpCodes.Call, columnInfoes[i].Type.GetConstructor(
new Type[] { Nullable.GetUnderlyingType(columnInfoes[i].Type) }));
il.Emit(OpCodes.Br_S, intCommon);
il.MarkLabel(intNull);
il.Emit(OpCodes.Initobj, columnInfoes[i].Type);
il.MarkLabel(intCommon);
il.Emit(OpCodes.Ldloc_S, item);
il.Emit(OpCodes.Ldloc, local);
il.Emit(OpCodes.Callvirt, columnInfoes[i].SetMethod);
}
private static void ReadInt64(ILGenerator il, LocalBuilder item,
List<DbColumnInfo> columnInfoes, LocalBuilder[] colIndices, int i)
{
il.Emit(OpCodes.Ldloc_S, item);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldloc_S, colIndices[i]);
il.Emit(OpCodes.Callvirt, DataRecord_GetInt64);
il.Emit(OpCodes.Callvirt, columnInfoes[i].SetMethod);
}
private static void ReadNullableInt64(ILGenerator il, LocalBuilder item,
List<DbColumnInfo> columnInfoes, LocalBuilder[] colIndices, int i)
{
var local = il.DeclareLocal(columnInfoes[i].Type);
Label intNull = il.DefineLabel();
Label intCommon = il.DefineLabel();
il.Emit(OpCodes.Ldloca, local);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldloc_S, colIndices[i]);
il.Emit(OpCodes.Callvirt, DataRecord_IsDBNull);
il.Emit(OpCodes.Brtrue_S, intNull);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldloc_S, colIndices[i]);
il.Emit(OpCodes.Callvirt, DataRecord_GetInt64);
il.Emit(OpCodes.Call, columnInfoes[i].Type.GetConstructor(
new Type[] { Nullable.GetUnderlyingType(columnInfoes[i].Type) }));
il.Emit(OpCodes.Br_S, intCommon);
il.MarkLabel(intNull);
il.Emit(OpCodes.Initobj, columnInfoes[i].Type);
il.MarkLabel(intCommon);
il.Emit(OpCodes.Ldloc_S, item);
il.Emit(OpCodes.Ldloc, local);
il.Emit(OpCodes.Callvirt, columnInfoes[i].SetMethod);
}
private static void ReadDecimal(ILGenerator il, LocalBuilder item,
MethodInfo setMethod, LocalBuilder colIndex)
{
il.Emit(OpCodes.Ldloc_S, item);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldloc_S, colIndex);
il.Emit(OpCodes.Callvirt, DataRecord_GetDecimal);
il.Emit(OpCodes.Callvirt, setMethod);
}
private static void ReadNullableDecimal(ILGenerator il, LocalBuilder item,
MethodInfo setMethod, LocalBuilder colIndex)
{
var local = il.DeclareLocal(typeof(decimal?));
Label decimalNull = il.DefineLabel();
Label decimalCommon = il.DefineLabel();
il.Emit(OpCodes.Ldloca, local);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldloc_S, colIndex);
il.Emit(OpCodes.Callvirt, DataRecord_IsDBNull);
il.Emit(OpCodes.Brtrue_S, decimalNull);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldloc_S, colIndex);
il.Emit(OpCodes.Callvirt, DataRecord_GetDecimal);
il.Emit(OpCodes.Call, typeof(decimal?).GetConstructor(new Type[] { typeof(decimal) }));
il.Emit(OpCodes.Br_S, decimalCommon);
il.MarkLabel(decimalNull);
il.Emit(OpCodes.Initobj, typeof(decimal?));
il.MarkLabel(decimalCommon);
il.Emit(OpCodes.Ldloc_S, item);
il.Emit(OpCodes.Ldloc, local);
il.Emit(OpCodes.Callvirt, setMethod);
}
private static void ReadFloat(ILGenerator il, LocalBuilder item,
MethodInfo setMethod, LocalBuilder colIndex)
{
il.Emit(OpCodes.Ldloc_S, item);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldloc_S, colIndex);
il.Emit(OpCodes.Callvirt, DataRecord_GetFloat);
il.Emit(OpCodes.Callvirt, setMethod);
}
private static void ReadNullableFloat(ILGenerator il, LocalBuilder item,
MethodInfo setMethod, LocalBuilder colIndex)
{
var local = il.DeclareLocal(typeof(float?));
Label decimalNull = il.DefineLabel();
Label decimalCommon = il.DefineLabel();
il.Emit(OpCodes.Ldloca, local);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldloc_S, colIndex);
il.Emit(OpCodes.Callvirt, DataRecord_IsDBNull);
il.Emit(OpCodes.Brtrue_S, decimalNull);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldloc_S, colIndex);
il.Emit(OpCodes.Callvirt, DataRecord_GetFloat);
il.Emit(OpCodes.Call, typeof(float?).GetConstructor(new Type[] { typeof(float) }));
il.Emit(OpCodes.Br_S, decimalCommon);
il.MarkLabel(decimalNull);
il.Emit(OpCodes.Initobj, typeof(float?));
il.MarkLabel(decimalCommon);
il.Emit(OpCodes.Ldloc_S, item);
il.Emit(OpCodes.Ldloc, local);
il.Emit(OpCodes.Callvirt, setMethod);
}
private static void ReadDouble(ILGenerator il, LocalBuilder item,
MethodInfo setMethod, LocalBuilder colIndex)
{
il.Emit(OpCodes.Ldloc_S, item);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldloc_S, colIndex);
il.Emit(OpCodes.Callvirt, DataRecord_GetDouble);
il.Emit(OpCodes.Callvirt, setMethod);
}
private static void ReadNullableDouble(ILGenerator il, LocalBuilder item,
MethodInfo setMethod, LocalBuilder colIndex)
{
var local = il.DeclareLocal(typeof(double?));
Label decimalNull = il.DefineLabel();
Label decimalCommon = il.DefineLabel();
il.Emit(OpCodes.Ldloca, local);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldloc_S, colIndex);
il.Emit(OpCodes.Callvirt, DataRecord_IsDBNull);
il.Emit(OpCodes.Brtrue_S, decimalNull);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldloc_S, colIndex);
il.Emit(OpCodes.Callvirt, DataRecord_GetDouble);
il.Emit(OpCodes.Call, typeof(double?).GetConstructor(new Type[] { typeof(double) }));
il.Emit(OpCodes.Br_S, decimalCommon);
il.MarkLabel(decimalNull);
il.Emit(OpCodes.Initobj, typeof(double?));
il.MarkLabel(decimalCommon);
il.Emit(OpCodes.Ldloc_S, item);
il.Emit(OpCodes.Ldloc, local);
il.Emit(OpCodes.Callvirt, setMethod);
}
private static void ReadDateTime(ILGenerator il, LocalBuilder item,
MethodInfo setMethod, LocalBuilder colIndex)
{
il.Emit(OpCodes.Ldloc_S, item);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldloc_S, colIndex);
il.Emit(OpCodes.Callvirt, DataRecord_GetDateTime);
il.Emit(OpCodes.Callvirt, setMethod);
}
private static void ReadNullableDateTime(ILGenerator il, LocalBuilder item,
MethodInfo setMethod, LocalBuilder colIndex)
{
var local = il.DeclareLocal(typeof(DateTime?));
Label dtNull = il.DefineLabel();
Label dtCommon = il.DefineLabel();
il.Emit(OpCodes.Ldloca, local);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldloc_S, colIndex);
il.Emit(OpCodes.Callvirt, DataRecord_IsDBNull);
il.Emit(OpCodes.Brtrue_S, dtNull);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldloc_S, colIndex);
il.Emit(OpCodes.Callvirt, DataRecord_GetDateTime);
il.Emit(OpCodes.Call, typeof(DateTime?).GetConstructor(new Type[] { typeof(DateTime) }));
il.Emit(OpCodes.Br_S, dtCommon);
il.MarkLabel(dtNull);
il.Emit(OpCodes.Initobj, typeof(DateTime?));
il.MarkLabel(dtCommon);
il.Emit(OpCodes.Ldloc_S, item);
il.Emit(OpCodes.Ldloc, local);
il.Emit(OpCodes.Callvirt, setMethod);
}
private static void ReadObject(ILGenerator il, LocalBuilder item,
List<DbColumnInfo> columnInfoes, LocalBuilder[] colIndices, int i)
{
Label common = il.DefineLabel();
il.Emit(OpCodes.Ldloc_S, item);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldloc_S, colIndices[i]);
il.Emit(OpCodes.Callvirt, DataRecord_ItemGetter_Int);
il.Emit(OpCodes.Dup);
il.Emit(OpCodes.Call, Convert_IsDBNull);
il.Emit(OpCodes.Brfalse_S, common);
il.Emit(OpCodes.Pop);
il.Emit(OpCodes.Ldnull);
il.MarkLabel(common);
il.Emit(OpCodes.Unbox_Any, columnInfoes[i].Type);
il.Emit(OpCodes.Callvirt, columnInfoes[i].SetMethod);
}
#endregion
#region Internal Methods
internal static IEnumerable<T> SelectDelay(IDataReader reader)
{
while (reader.Read())
yield return DataLoader(reader);
}
internal static List<T> Select(IDataReader reader)
{
return BatchDataLoader(reader);
}
#endregion
}
#endregion
}
}
数据库连接类
抽象类:
using DBExtensions;
using System;
using System.Collections.Generic;
using System.Data;
namespace DAL
{
public abstract class BasicDataAccess
{
protected IDbConnection conn = null;
#region protected Method
public T ExecuteScalar<T>(string sql, Dictionary<string, object> parameters = null)
{
T Result = (T)Convert.ChangeType(ExecuteScalar(sql,parameters), typeof(T));
return Result;
}
/// <summary>
/// 返回select语句唯一值,
/// </summary>
/// <param name="sql"></param>
/// <param name="parameters"></param>
/// <returns></returns>
public dynamic ExecuteScalar(string sql, Dictionary<string, object> parameters = null)
{
Open();
IDbCommand command = GetCmd();
command.CommandType = CommandType.Text;
command.CommandText = sql;
SetParameter(command, parameters);
dynamic result = command.ExecuteScalar();
Close();
return result;
}
/// <summary>
/// 返回影响行数,处理非select语句
/// </summary>
/// <param name="sql"></param>
/// <param name="parameters"></param>
/// <returns></returns>
public int ExecuteNonQuery(string sql, Dictionary<string, object> parameters = null)
{
Open();
IDbCommand command = GetCmd();
command.CommandType = CommandType.Text;
command.CommandText = sql;
SetParameter(command, parameters);
int nR = command.ExecuteNonQuery();
Close();
return nR;
}
public int ExecuteNonQuery(string sql, List<DBTypeExt> DBType, Dictionary<string, object> parameters = null)
{
Open();
IDbCommand command = GetCmd();
command.CommandType = CommandType.Text;
command.CommandText = sql;
SetParameter(command, DBType, parameters);
int nR = command.ExecuteNonQuery();
Close();
return nR;
}
public List<T> Query<T>(string strSql, Dictionary<string, object> parameters = null) where T : class, new()
{
Open();
IDbCommand command = GetCmd();
command.CommandType = CommandType.Text;
command.CommandText = strSql;
SetParameter(command, parameters);
IDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection);
List<T> result = reader.Select<T>();
Close();
return result;
}
public IDataReader GetDataReader(string strSql, Dictionary<string, object> parameters = null)
{
IDataReader reader = null;
try
{
Open();
IDbCommand command = GetCmd();
command.CommandType = CommandType.Text;
command.CommandText = strSql;
SetParameter(command, parameters);
reader = command.ExecuteReader(CommandBehavior.CloseConnection);
}
catch
{
Close();
throw;
}
return reader;
}
#endregion
#region 抽象方法
public abstract void Open();
protected abstract void SetParameter(IDbCommand command, Dictionary<string, object> parameters);
protected abstract void SetParameter(IDbCommand command, List<DBTypeExt> DbTypes, Dictionary<string, object> parameters);
protected abstract IDbDataAdapter GetDataAdapter(IDbCommand command);
#endregion
#region GetDataTable
public DataTable GetDataTable(string strSql, Dictionary<string, object> parameters=null)
{
DataSet dataSet = new DataSet();
IDbCommand command = null;
try
{
Open();
command = GetCmd();
command.CommandType = CommandType.Text;
command.CommandText = strSql;
SetParameter(command, parameters);
IDataAdapter adapter = GetDataAdapter(command);
adapter.Fill(dataSet);
return dataSet.Tables[0];
}
catch (Exception ex)
{
dataSet.Clear();
throw ex;
}
finally
{
command.Dispose();
Close();
}
}
/// <summary>
/// </summary>
/// <param name="sqls"></param>
/// <param name="nErrI"></param>
/// <returns></returns>
public bool DB_Transaction(List<String> sqls, ref int nErrI,ref string strErr)
{
IDbCommand command = null;
try
{
Open();
IDbConnection conn = GetConn();
command = GetCmd();
command.Transaction = conn.BeginTransaction();
nErrI = 0;
foreach (string sql in sqls)
{
command.CommandText = sql;
command.ExecuteNonQuery();
nErrI++;
}
command.Transaction.Commit();
return true;
}
catch (Exception e)
{
if (command.Transaction != null)
{
command.Transaction.Rollback();//回滚事务
}
strErr = e.Message;
}
finally
{
command.Dispose();
Close();
}
return false;
}
public bool DB_Transaction(List<sqlParameter> sqls, ref int nErrI, ref string strErr)
{
IDbCommand command = null;
try
{
Open();
IDbConnection conn = GetConn();
command = GetCmd();
command.Transaction = conn.BeginTransaction();
nErrI = 0;
foreach (sqlParameter item in sqls)
{
command.CommandType = CommandType.Text;
command.CommandText = item.sql;
command.Parameters.Clear();
SetParameter(command, item.paramTypes, item.dictParams);
command.ExecuteNonQuery();
nErrI++;
}
command.Transaction.Commit();
return true;
}
catch (Exception e)
{
if (command.Transaction != null)
{
command.Transaction.Rollback();
}
strErr = e.Message;
}
finally
{
command.Dispose();
Close();
}
return false;
}
#endregion
#region 受保护方法GetConn(),GetCmd(),Close()
protected IDbConnection GetConn()
{
return conn;
}
protected IDbCommand GetCmd()
{
return conn.CreateCommand();
}
public void Close()
{
if (conn != null && conn.State == ConnectionState.Open)
{
try
{
conn.Close();
conn = null;
}
catch (Exception ex)
{
throw ex;
}
}
}
#endregion
}
}
oracle子类
using System;
using System.Data;
using Oracle.ManagedDataAccess.Client;
using System.Collections.Generic;
using DBExtensions;
namespace DAL
{
/// <summary>
/// 1.目前此类不支持以参数形式insert update select操作BLOB字段不太好;
/// 2.此类不打算支持short、byte、bool类型字段;
/// </summary>
public class OracleDataAccess : BasicDataAccess, IDisposable
{
private string _strConn = string.Empty;
public OracleDataAccess()
{
_strConn = System.Configuration.ConfigurationManager.ConnectionStrings["conn"].ToString();
}
public OracleDataAccess(string strConn)
{
_strConn = strConn;
}
public override void Open()
{
try
{
if (conn == null)
{
conn = new OracleConnection(_strConn);
}
if (conn.State != ConnectionState.Open)
conn.Open();
}
catch (Exception ex)
{
throw ex;
}
}
protected override IDbDataAdapter GetDataAdapter(IDbCommand command)
{
IDbDataAdapter dbadapter = new OracleDataAdapter((OracleCommand)command);
return dbadapter;
}
protected override void SetParameter(IDbCommand command, Dictionary<string, object> parameters)
{
if (parameters == null)
return;
foreach (KeyValuePair<string, object> kvp in parameters)
{
OracleParameter p = new OracleParameter(kvp.Key, kvp.Value);
command.Parameters.Add(p);
}
}
protected override void SetParameter(IDbCommand command, List<DBTypeExt> DBTypes, Dictionary<string, object> parameters)
{
if (parameters == null)
return;
int nIndex = 0;
foreach (KeyValuePair<string, object> kvp in parameters)
{
OracleParameter p = new OracleParameter(kvp.Key, (OracleDbType)DBTypes[nIndex], kvp.Value, ParameterDirection.Input);
command.Parameters.Add(p);
nIndex++;
}
}
public void Dispose()
{
Close();
}
}
}
db扩展:
DBExtensions类
using System;
namespace DBExtensions
{
/// <summary>
/// 标示该属性是(或不是)数据列
/// </summary>
[AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)]
public sealed class DbColumnAttribute : Attribute
{
/// <summary>
/// 列名(缺省时使用属性名)
/// </summary>
public string ColumnName { get; set; }
/// <summary>
/// 是否强制忽略该属性
/// </summary>
public bool Ignore { get; set; }
/// <summary>
/// 可选数据列(Reader中不存在该列时,保持默认值)
/// </summary>
public bool IsOptional { get; set; }
}
/// <summary>
/// 标示该类为数据库的结果集实体
/// </summary>
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
public sealed class DbResultAttribute : Attribute
{
/// <summary>
/// 默认所有属性是数据列
/// </summary>
public DbResultAttribute()
: this(true) { }
/// <summary>
/// 默认所有属性是(或不是)数据列
/// </summary>
/// <param name="defaultAsDbColumn">默认是数据列</param>
public DbResultAttribute(bool defaultAsDbColumn)
{
DefaultAsDbColumn = defaultAsDbColumn;
}
/// <summary>
/// 默认是数据列
/// </summary>
public bool DefaultAsDbColumn { get; private set; }
}
}
表模型attribute
using System;
namespace DBExtensions
{
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
public sealed class DBEntityAttribute : Attribute
{
/// <summary>
/// 表名或者视图名,或者是作为视图的sql语句
/// </summary>
public string EntityName { set; get; }
/// <summary>
/// 主键
/// </summary>
public string EntityPK { set; get; }
/// <summary>
/// 是否有大字段(geom、clob)
/// </summary>
public bool haveLargeField { set; get;}
/// <summary>
/// 对应数据库字段参数类型
/// </summary>
public DBTypeExt[] ParamTypes { set; get; }
}
[AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = true)]
public sealed class DBDetailAttribute : Attribute
{
/// <summary>
/// 是否CLOB字段
/// </summary>
public bool ClobField { set; get; }
/// <summary>
/// 是否GEOM字段
/// </summary>
public bool GeomField { set; get; }
}
}
数据库参数类型扩展
using System.Collections.Generic;
namespace DBExtensions
{
public enum DBTypeExt
{
orclBFile = 101,
orclBlob = 102,
orclByte = 103,
orclChar = 104,
orclClob = 105,
orclDate = 106,
orclDecimal = 107,
orclDouble = 108,
orclLong = 109,
orclLongRaw = 110,
orclInt16 = 111,
orclInt32 = 112,
orclInt64 = 113,
orclIntervalDS = 114,
orclIntervalYM = 115,
orclNClob = 116,
orclNChar = 117,
orclNVarchar2 = 119,
orclRaw = 120,
orclRefCursor = 121,
orclSingle = 122,
orclTimeStamp = 123,
orclTimeStampLTZ = 124,
orclTimeStampTZ = 125,
orclVarchar2 = 126,
orclXmlType = 127,
orclBinaryDouble = 132,
orclBinaryFloat = 133
}
public struct sqlParameter
{
public string sql;
public Dictionary<string, object> dictParams;
public List<DBTypeExt> paramTypes;
public sqlParameter(string s, Dictionary<string, object> ps, List<DBTypeExt> ts)
{
sql = s;
dictParams = ps;
paramTypes = ts;
}
}
}