public IEnumerable <T> ReadAll(object param) { ParameterException.Check(param != null, ParameterError.NotExistParameter); DbCommand command = EntityManager.Connection.CreateCommand(); command.CommandText = QueryBuilder.ReadAll(param); command.CommandType = CommandType.Text; if (!ParameterGeneratorCache.ContainsKey(param.GetType())) { ParameterGeneratorCache.Add(param.GetType(), CreateParamInfoGenerator(param)); } var fillParameterGenerator = ParameterGeneratorCache[param.GetType()]; fillParameterGenerator(command, param); EntityManager.Connection.Open(); using (var reader = command.ExecuteReader()) { if (!ConstructInstanceCache.ContainsKey(typeof(T))) { ConstructInstanceCache.Add(typeof(T), CreateConstructInstance(reader)); } var constructingInstance = ConstructInstanceCache[typeof(T)]; while (reader.Read()) { object row = constructingInstance(reader); yield return((T)row); } } EntityManager.Connection.Close(); }
public async Task <T> CreateAsync(T data) { ParameterException.Check(data != null, ParameterError.NotExistData); DbCommand command = EntityManager.Connection.CreateCommand(); command.CommandText = QueryBuilder.Create(data); command.CommandType = CommandType.Text; if (!ParameterGeneratorCache.ContainsKey(data.GetType())) { ParameterGeneratorCache.Add(data.GetType(), CreateParamInfoGenerator(data)); } var fillParameterGenerator = ParameterGeneratorCache[data.GetType()]; fillParameterGenerator(command, data); await EntityManager.Connection.OpenAsync().ConfigureAwait(false); var id = Convert.ToInt32(await command.ExecuteScalarAsync().ConfigureAwait(false)); EntityManager.Connection.Close(); if (!ConstructDataInstanceCache.ContainsKey(typeof(T))) { ConstructDataInstanceCache.Add(typeof(T), CreateConstructDataInstance()); } var constructingInstance = ConstructDataInstanceCache[typeof(T)]; var result = constructingInstance(data, id); return(result); }
//DataReader로 부터 값들을 읽어 인스턴스를 만든다 private ConstructInstance CreateConstructInstance(IDataReader reader) { ParameterException.Check(reader != null, ParameterError.NotExistReader); var type = typeof(T); var dynamicMethod = new DynamicMethod("ConstructInstance", type, new[] { typeof(IDataReader) }, type); var il = dynamicMethod.GetILGenerator(); Label startLoop = il.DefineLabel(); Label endLoop = il.DefineLabel(); ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes); il.Emit(OpCodes.Newobj, constructor); //[instance] il.MarkLabel(startLoop); PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (PropertyInfo property in properties) { Label startValueTypeNullLoop = il.DefineLabel(); Label endValueTypeNullLoop = il.DefineLabel(); Label jumpToEnd = il.DefineLabel(); var columnAttribute = property.GetCustomAttribute <ColumnAttribute>(); AttributeException.Check(columnAttribute != null, AttributeError.NotExistColumnAttribute); var columnName = columnAttribute.Name ?? property.Name; //SetValue il.Emit(OpCodes.Dup); //[instance][instance] il.Emit(OpCodes.Ldarg_0); //[instance][instance][IDataReader] il.Emit(OpCodes.Ldstr, columnName); //[instance][instance][IDataReader][Name] il.Emit(OpCodes.Call, typeof(IDataReaderHelper).GetMethod(nameof(IDataReaderHelper .GetValue))); //[instance][instance][value] il.Emit(OpCodes.Dup); //[instance][instance][value][value] il.Emit(OpCodes.Ldsfld, typeof(DBNull).GetField(nameof(DBNull.Value))); //[instance][instance][value][value][DBNullValue] il.Emit(OpCodes.Ceq); // [instance][instance][value][result] il.Emit(OpCodes.Brtrue, startValueTypeNullLoop); //[instance][instance] if (property.PropertyType.IsValueType) { il.Emit(OpCodes.Unbox_Any, property.PropertyType); //[instance][instance][unbox_value] } il.MarkLabel(endValueTypeNullLoop); il.Emit(OpCodes.Call, property.GetSetMethod()); //[instance] il.Emit(OpCodes.Br, jumpToEnd); il.MarkLabel(startValueTypeNullLoop); if (property.PropertyType.IsValueType) { il.Emit(OpCodes.Pop); //[instance][instance] il.Emit(OpCodes.Ldc_I4_0); //[instance][instance][0] } il.Emit(OpCodes.Br, endValueTypeNullLoop); il.MarkLabel(jumpToEnd); } il.MarkLabel(endLoop); il.Emit(OpCodes.Ret); return((ConstructInstance)dynamicMethod.CreateDelegate(typeof(ConstructInstance))); }
//param으로부터 값들을 받아 Parameter를 채운다 private FillParamInfoGenerator CreateParamInfoGenerator(object param) { ParameterException.Check(param != null, ParameterError.NotExistParameter); var parameterType = param.GetType(); var propertyInfos = parameterType.GetProperties(); var dynamicMethod = new DynamicMethod("CreateParameterGenerator", null, new[] { typeof(IDbCommand), typeof(object) }); var il = dynamicMethod.GetILGenerator(); var commandIL = il.DeclareLocal(typeof(IDbCommand)); il.Emit(OpCodes.Ldarg_0); //[DbCommand] il.Emit(OpCodes.Stloc, commandIL); //Empty foreach (var property in propertyInfos) { il.Emit(OpCodes.Ldloc, commandIL); //[DbCommand] il.Emit(OpCodes.Callvirt, typeof(IDbCommand).GetProperty(nameof(IDbCommand.Parameters)).GetGetMethod()); //[Parameters] il.Emit(OpCodes.Ldloc, commandIL); //[Parameters][Dbcommand] il.Emit(OpCodes.Callvirt, typeof(IDbCommand).GetMethod(nameof(IDbCommand.CreateParameter))); //[Parameters] [DbParameter] // SetName il.Emit(OpCodes.Dup); //[Parameters][DbParameter][DbParameter] il.Emit(OpCodes.Ldstr, property.Name); //[Parameters][DbParameter][DbParameter][Name] il.Emit(OpCodes.Callvirt, typeof(IDataParameter).GetProperty(nameof(IDbDataParameter.ParameterName)) .GetSetMethod()); //[Parameters][DbParameter] // SetDbType DbType dbType = LookupDbType(property.PropertyType); il.Emit(OpCodes.Dup); //[Parameters][DbParameter][DbParameter] il.Emit(OpCodes.Ldc_I4, (int)dbType); //[Parameters][DbParameter][DbParameter][dbType-num] il.EmitCall(OpCodes.Callvirt, typeof(IDataParameter).GetProperty(nameof(IDataParameter.DbType)).GetSetMethod(), null); //[Parameters][DbParameter] // SetValue il.Emit(OpCodes.Dup); //[Parameters][DbParameter][DbParameter] il.Emit(OpCodes.Ldarg_1); ////[Parameters][DbParameter][DbParameter][object] il.Emit(OpCodes.Call, property.GetGetMethod()); //[Parameters][DbParameter][DbParameter][Value] if (property.PropertyType.IsValueType) { il.Emit(OpCodes.Box, property.PropertyType); //[Parameters][DbParameter][DbParameter][boxed-Value] } il.Emit(OpCodes.Callvirt, typeof(IDataParameter).GetProperty(nameof(IDataParameter.Value)) .GetSetMethod()); //[Parameters][DbParameter] il.Emit(OpCodes.Callvirt, typeof(IList).GetMethod(nameof(IList.Add))); //[int] il.Emit(OpCodes.Pop); } il.Emit(OpCodes.Ret); return((FillParamInfoGenerator)dynamicMethod.CreateDelegate(typeof(FillParamInfoGenerator))); }
public async Task <IEnumerable <T> > ReadAllAsync(object param) { DbDataReader reader = null; IEnumerable <T> result = null; bool isClosed = EntityManager.Connection.State == ConnectionState.Closed; ParameterException.Check(param != null, ParameterError.NotExistParameter); DbCommand command = EntityManager.Connection.CreateCommand(); command.CommandText = QueryBuilder.ReadAll(param); command.CommandType = CommandType.Text; if (!ParameterGeneratorCache.ContainsKey(param.GetType())) { ParameterGeneratorCache.Add(param.GetType(), CreateParamInfoGenerator(param)); } var fillParameterGenerator = ParameterGeneratorCache[param.GetType()]; fillParameterGenerator(command, param); var source = new CancellationTokenSource(); var cancelToken = source.Token; var behavior = CommandBehavior.SequentialAccess | CommandBehavior.SingleResult; try { await EntityManager.Connection.OpenAsync().ConfigureAwait(false); reader = await command.ExecuteReaderAsync(GetBehavior(isClosed, behavior), cancelToken) .ConfigureAwait(false); if (!ConstructInstanceCache.ContainsKey(typeof(T))) { ConstructInstanceCache.Add(typeof(T), CreateConstructInstance(reader)); } var constructingInstance = ConstructInstanceCache[typeof(T)]; isClosed = false; result = ExecuteReaderSync(reader, constructingInstance); return(result); } finally { if (isClosed) { EntityManager.Connection.Close(); } } }
public void DeleteAll(object param) { ParameterException.Check(param != null, ParameterError.NotExistParameter); DbCommand command = EntityManager.Connection.CreateCommand(); command.CommandText = QueryBuilder.DeleteAll(param); command.CommandType = CommandType.Text; if (!ParameterGeneratorCache.ContainsKey(param.GetType())) { ParameterGeneratorCache.Add(param.GetType(), CreateParamInfoGenerator(param)); } var fillParameterGenerator = ParameterGeneratorCache[param.GetType()]; fillParameterGenerator(command, param); EntityManager.Connection.Open(); command.ExecuteNonQuery(); EntityManager.Connection.Close(); }
public void Update(int id, T data) { ParameterException.Check(data != null, ParameterError.NotExistData); DbCommand command = EntityManager.Connection.CreateCommand(); command.CommandText = QueryBuilder.Update(id, data); command.CommandType = CommandType.Text; if (!DataParamGeneratorCache.ContainsKey(data.GetType())) { DataParamGeneratorCache.Add(data.GetType(), CreateDataInfoGenerator(data, id)); } var fillParameterGenerator = DataParamGeneratorCache[data.GetType()]; fillParameterGenerator(command, data, id); EntityManager.Connection.Open(); command.ExecuteNonQuery(); EntityManager.Connection.Close(); }
//Parameter의 @id 부분은 id로, 나머지는 data의 값을 채워넣는다 private FillDataInfoGenerator CreateDataInfoGenerator(Object data, int id) { ParameterException.Check(data != null, ParameterError.NotExistData); var type = data.GetType(); var propertyInfos = type.GetProperties(); ColumnInfos = type.GetProperties() .Select(info => new ColumnInfo(info, info.GetCustomAttribute <ColumnAttribute>())) .Where(info => info.ColumnAttribute != null).ToArray(); var primaryKey = ColumnInfos.FirstOrDefault(info => info.PropertyInfo.IsDefined(typeof(PrimaryKeyAttribute))); var dynamicMethod = new DynamicMethod("CreateDataInfoGenerator", null, new[] { typeof(IDbCommand), typeof(object), typeof(int) }); var il = dynamicMethod.GetILGenerator(); var commandIL = il.DeclareLocal(typeof(IDbCommand)); il.Emit(OpCodes.Ldarg_0); //[DbCommand] il.Emit(OpCodes.Stloc, commandIL); //Empty foreach (var property in propertyInfos) { Label isIDProperty = il.DefineLabel(); Label endSetValue = il.DefineLabel(); il.Emit(OpCodes.Ldloc, commandIL); //[DbCommand] il.Emit(OpCodes.Callvirt, typeof(IDbCommand).GetProperty(nameof(IDbCommand.Parameters)).GetGetMethod()); //[Parameters] il.Emit(OpCodes.Ldloc, commandIL); //[Parameters][Dbcommand] il.Emit(OpCodes.Callvirt, typeof(IDbCommand).GetMethod(nameof(IDbCommand.CreateParameter))); //[Parameters] [DbParameter] // SetName il.Emit(OpCodes.Dup); //[Parameters][DbParameter][DbParameter] il.Emit(OpCodes.Ldstr, property.Name); //[Parameters][DbParameter][DbParameter][Name] il.Emit(OpCodes.Callvirt, typeof(IDataParameter).GetProperty(nameof(IDbDataParameter.ParameterName)) .GetSetMethod()); //[Parameters][DbParameter] // SetDbType DbType dbType = LookupDbType(property.PropertyType); il.Emit(OpCodes.Dup); //[Parameters][DbParameter][DbParameter] il.Emit(OpCodes.Ldc_I4, (int)dbType); //[Parameters][DbParameter][DbParameter][dbType-num] il.EmitCall(OpCodes.Callvirt, typeof(IDataParameter).GetProperty(nameof(IDataParameter.DbType)).GetSetMethod(), null); //[Parameters][DbParameter] if (property.Name.ToLower() == primaryKey.Name.ToLower()) { //SetIDValue il.Emit(OpCodes.Dup); //[Parameters][DbParameter][DbParameter] il.Emit(OpCodes.Ldarg_2); //[Parameters][DbParameter][DbParameter][Value] } else { // SetValue il.Emit(OpCodes.Dup); //[Parameters][DbParameter][DbParameter] il.Emit(OpCodes.Ldarg_1); ////[Parameters][DbParameter][DbParameter][object] il.Emit(OpCodes.Call, property.GetGetMethod()); //[Parameters][DbParameter][DbParameter][Value] } if (property.PropertyType.IsValueType) { il.Emit(OpCodes.Box, property.PropertyType); //[Parameters][DbParameter][DbParameter][boxed-Value] } il.Emit(OpCodes.Callvirt, typeof(IDataParameter).GetProperty(nameof(IDataParameter.Value)) .GetSetMethod()); //[Parameters][DbParameter] il.Emit(OpCodes.Callvirt, typeof(IList).GetMethod(nameof(IList.Add))); //[int] il.Emit(OpCodes.Pop); } il.Emit(OpCodes.Ret); return((FillDataInfoGenerator)dynamicMethod.CreateDelegate(typeof(FillDataInfoGenerator))); }