static Func <IDataReader, T> CreateObjectReader <T>( DataConnection dataConnection, IDataReader dataReader, Func <Type, int, Expression, Expression> getMemberExpression) { var parameter = Expression.Parameter(typeof(IDataReader)); var dataReaderExpr = Expression.Convert(parameter, dataReader.GetType()); Expression expr; if (dataConnection.MappingSchema.IsScalarType(typeof(T))) { expr = getMemberExpression(typeof(T), 0, dataReaderExpr); } else { var td = dataConnection.MappingSchema.GetEntityDescriptor(typeof(T)); var names = new List <string>(dataReader.FieldCount); for (var i = 0; i < dataReader.FieldCount; i++) { names.Add(dataReader.GetName(i)); } expr = null; var ctors = typeof(T).GetConstructors().Select(c => new { c, ps = c.GetParameters() }).ToList(); if (ctors.Count > 0 && ctors.All(c => c.ps.Length > 0)) { var q = from c in ctors let count = c.ps.Count(p => names.Contains(p.Name)) orderby count descending select c; var ctor = q.FirstOrDefault(); if (ctor != null) { expr = Expression.New( ctor.c, ctor.ps.Select(p => names.Contains(p.Name) ? getMemberExpression(p.ParameterType, names.IndexOf(p.Name), dataReaderExpr) : Expression.Constant(dataConnection.MappingSchema.GetDefaultValue(p.ParameterType), p.ParameterType))); } } if (expr == null) { var members = ( from n in names.Select((name, idx) => new { name, idx }) let member = td.Columns.FirstOrDefault(m => string.Compare(m.ColumnName, n.name, dataConnection.MappingSchema.ColumnComparisonOption) == 0) where member != null select new { Member = member, Expr = getMemberExpression(member.MemberType, n.idx, dataReaderExpr), } ).ToList(); expr = Expression.MemberInit( Expression.New(typeof(T)), members.Select(m => Expression.Bind(m.Member.MemberInfo, m.Expr))); } } if (expr.GetCount(e => e == dataReaderExpr) > 1) { var dataReaderVar = Expression.Variable(dataReaderExpr.Type, "dr"); var assignment = Expression.Assign(dataReaderVar, dataReaderExpr); expr = expr.Transform(e => e == dataReaderExpr ? dataReaderVar : e); expr = Expression.Block(new[] { dataReaderVar }, new[] { assignment, expr }); } var lex = Expression.Lambda <Func <IDataReader, T> >(expr, parameter); return(lex.Compile()); }
public CommandInfo(DataConnection dataConnection, string commandText, object parameters) { DataConnection = dataConnection; CommandText = commandText; Parameters = GetDataParameters(dataConnection, parameters); }
public CommandInfo(DataConnection dataConnection, string commandText, DataParameter parameter) { DataConnection = dataConnection; CommandText = commandText; Parameters = new[] { parameter }; }
static DataParameter[] GetDataParameters(DataConnection dataConnection, object parameters) { if (parameters == null) { return(null); } if (parameters is DataParameter[]) { return((DataParameter[])parameters); } if (parameters is DataParameter) { return new[] { (DataParameter)parameters } } ; Func <object, DataParameter[]> func; var type = parameters.GetType(); var key = new ParamKey(type, dataConnection.ID); if (!_parameterReaders.TryGetValue(key, out func)) { var td = dataConnection.MappingSchema.GetEntityDescriptor(type); var p = Expression.Parameter(typeof(object), "p"); var obj = Expression.Parameter(parameters.GetType(), "obj"); var expr = Expression.Lambda <Func <object, DataParameter[]> >( Expression.Block( new[] { obj }, new Expression[] { Expression.Assign(obj, Expression.Convert(p, type)), Expression.NewArrayInit( typeof(DataParameter), td.Columns.Select(m => { if (m.MemberType == typeof(DataParameter)) { var pobj = Expression.Parameter(typeof(DataParameter)); return(Expression.Block( new[] { pobj }, new Expression[] { Expression.Assign(pobj, Expression.PropertyOrField(obj, m.MemberName)), Expression.MemberInit( Expression.New(typeof(DataParameter)), Expression.Bind( _dataParameterName, Expression.Coalesce( Expression.MakeMemberAccess(pobj, _dataParameterName), Expression.Constant(m.ColumnName))), Expression.Bind( _dataParameterDataType, Expression.MakeMemberAccess(pobj, _dataParameterDataType)), Expression.Bind( _dataParameterValue, Expression.Convert( Expression.MakeMemberAccess(pobj, _dataParameterValue), typeof(object)))) })); } var memberType = m.MemberType.ToNullableUnderlying(); var valueGetter = Expression.PropertyOrField(obj, m.MemberName) as Expression; var mapper = dataConnection.MappingSchema.GetConvertExpression(memberType, typeof(DataParameter), createDefault: false); if (mapper != null) { return(Expression.Call( MemberHelper.MethodOf(() => PrepareDataParameter(null, null)), mapper.GetBody(valueGetter), Expression.Constant(m.ColumnName))); } if (memberType.IsEnumEx()) { var mapType = ConvertBuilder.GetDefaultMappingFromEnumType(dataConnection.MappingSchema, memberType); var convExpr = dataConnection.MappingSchema.GetConvertExpression(m.MemberType, mapType); memberType = mapType; valueGetter = convExpr.GetBody(valueGetter); } return((Expression)Expression.MemberInit( Expression.New(typeof(DataParameter)), Expression.Bind( _dataParameterName, Expression.Constant(m.ColumnName)), Expression.Bind( _dataParameterDataType, Expression.Constant(dataConnection.MappingSchema.GetDataType(memberType).DataType)), Expression.Bind( _dataParameterValue, Expression.Convert(valueGetter, typeof(object))))); })) } ), p); _parameterReaders[key] = func = expr.Compile(); } return(func(parameters)); }
public CommandInfo(DataConnection dataConnection, string commandText, params DataParameter[] parameters) { DataConnection = dataConnection; CommandText = commandText; Parameters = parameters; }
public CommandInfo(DataConnection dataConnection, string commandText) { DataConnection = dataConnection; CommandText = commandText; }