コード例 #1
0
ファイル: ModelCache.cs プロジェクト: gonbike/Destrier
 public static SetInstanceValuesDelegate GetSetInstanceValuesDelegate(IndexedSqlDataReader reader)
 {
     return(_setInstanceValuesDelegateCache.GetOrAdd(reader.GetCacheId(), (id) =>
     {
         return Model.GenerateSetInstanceValuesDelegate(reader);
     }));
 }
コード例 #2
0
ファイル: Execute.cs プロジェクト: gonbike/Destrier
        public static T Statement <T>(String statement, dynamic parameters = null, String connectionName = null)
        {
            using (var cmd = Command(connectionName))
            {
                cmd.CommandType = System.Data.CommandType.Text;
                cmd.CommandText = statement;

                if (parameters != null)
                {
                    Utility.AddParametersToCommand(parameters, cmd);
                }

                var type = typeof(T);

                using (var dr = new IndexedSqlDataReader(cmd.ExecuteReader(CommandBehavior.CloseConnection)))
                {
                    if (dr.Read())
                    {
                        if (type.IsValueType || type.Equals(typeof(String)) || type.Equals(typeof(DateTime)))
                        {
                            return(dr.Get <T>(0));
                        }

                        return(dr.ReadObject <T>(returnNullOnEmpty: true));
                    }
                    else
                    {
                        return(default(T));
                    }
                }
            }
        }
コード例 #3
0
ファイル: ColumnAttribute.cs プロジェクト: gonbike/Destrier
 public void Populate(IndexedSqlDataReader dr)
 {
     this.Name            = dr.Get <String>("name");
     this.CanBeNull       = dr.Get <Boolean>("is_nullable");
     this.MaxStringLength = dr.Get <Int32>("max_length");
     this.IsAutoIdentity  = dr.Get <Boolean>("is_identity");
     this.IsPrimaryKey    = dr.Get <Boolean>("is_primarykey");
 }
コード例 #4
0
ファイル: Model.cs プロジェクト: gonbike/Destrier
        public static void Populate(object instance, IndexedSqlDataReader dr)
        {
            var thisType = instance.GetType();
            var members  = ModelCache.GetColumnMemberLookup(thisType);

            foreach (var col in members.Values)
            {
                col.SetValue(instance, dr.Get(col));
            }
        }
コード例 #5
0
        private IEnumerable <T> _fastPipeline()
        {
            var connectionName = Model.ConnectionName(_t);

            using (var cmd = Destrier.Execute.Command(connectionName))
            {
                cmd.CommandText = this.QueryBody;
                cmd.CommandType = System.Data.CommandType.Text;
                Destrier.Execute.Utility.AddParametersToCommand(_parameters, cmd, connectionName);
                using (var dr = new IndexedSqlDataReader(cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection), type: _t))
                {
                    while (dr.Read())
                    {
                        T newObject = (T)ReflectionHelper.GetNewObject(_t);
                        dr.DeepPopulate(newObject, _t);
                        yield return(newObject);
                    }
                }
            }
        }
コード例 #6
0
        /// <summary>
        /// Throws a data exception produced by the _setInstanceValuesFn.
        /// </summary>
        /// <param name="ex"></param>
        /// <param name="columnIndex"></param>
        /// <param name="instance"></param>
        /// <param name="reader"></param>
        public static void ThrowDataException(Exception ex, Int32 columnIndex, Object instance, IndexedSqlDataReader reader)
        {
            Exception toThrow;

            try
            {
                string name       = "-";
                string value      = "-";
                string memberName = "-";
                string memberType = "-";
                if (reader != null && columnIndex >= 0 && columnIndex < reader.FieldCount)
                {
                    name = reader.GetName(columnIndex);
                    object val = reader.GetValue(columnIndex);
                    if (val == null || val is DBNull)
                    {
                        value = "null";
                    }
                    else
                    {
                        value = Convert.ToString(val) + " as " + Type.GetTypeCode(val.GetType());
                    }

                    if (reader.ColumnMemberIndexMap != null && reader.ColumnMemberIndexMap.Any())
                    {
                        memberName = reader.ColumnMemberIndexMap[columnIndex].Name;
                        memberType = reader.ColumnMemberIndexMap[columnIndex].Type.ToString();
                    }
                }
                toThrow = new DataException(String.Format("Exception reading column {0}: ({1} = {2}) for {3} as {4})", columnIndex, name, value, memberName, memberType), ex);
            }
            catch
            {
                toThrow = new DataException(ex.Message, ex);
            }
            throw toThrow;
        }
コード例 #7
0
 /// <summary>
 /// Implementation of Populate.
 /// </summary>
 /// <param name="dr"></param>
 public void Populate(IndexedSqlDataReader dr)
 {
     this.TableName = dr.Get <String>("name");
 }
コード例 #8
0
ファイル: Model.cs プロジェクト: gonbike/Destrier
        public static SetInstanceValuesDelegate GenerateSetInstanceValuesDelegate(IndexedSqlDataReader dr)
        {
            Type idr         = typeof(IndexedSqlDataReader);
            var  idr_methods = new Dictionary <String, MethodInfo>();

            foreach (var mi in idr.GetMethods())
            {
                if (mi.Name.StartsWith("Get") || mi.Name == "IsDBNull")
                {
                    if (!idr_methods.ContainsKey(mi.Name))
                    {
                        idr_methods.Add(mi.Name, mi);
                    }
                }
            }

            var get_value_fn = idr_methods["GetValue"];
            var get_guid_fn  = idr_methods["GetGuid"];
            var is_dbnull    = idr_methods["IsDBNull"];

            //use this with the type code on the dr field.
            var type_accessors = new Dictionary <TypeCode, MethodInfo>()
            {
                { TypeCode.Boolean, idr_methods["GetBoolean"] },
                { TypeCode.DateTime, idr_methods["GetDateTime"] },
                { TypeCode.UInt16, idr_methods["GetInt16"] },
                { TypeCode.Int16, idr_methods["GetInt16"] },
                { TypeCode.UInt32, idr_methods["GetInt32"] },
                { TypeCode.Int32, idr_methods["GetInt32"] },
                { TypeCode.UInt64, idr_methods["GetInt64"] },
                { TypeCode.Int64, idr_methods["GetInt64"] },
                { TypeCode.Single, idr_methods["GetDouble"] },
                { TypeCode.Double, idr_methods["GetDouble"] },
                { TypeCode.Decimal, idr_methods["GetDecimal"] },
                { TypeCode.String, idr_methods["GetString"] },
                { TypeCode.Char, idr_methods["GetString"] },
                { TypeCode.Byte, idr_methods["GetByte"] }
            };

            DynamicMethod dyn = new DynamicMethod("SetInstanceValues", typeof(void), new Type[] { typeof(IndexedSqlDataReader), typeof(object) });
            ILGenerator   il  = dyn.GetILGenerator();

            var defaults = new Dictionary <TypeCode, Action>()
            {
                { TypeCode.Boolean, () => { il.Emit(OpCodes.Ldc_I4_0); } },
                { TypeCode.Int16, () => { il.Emit(OpCodes.Ldc_I4_0); } },
                { TypeCode.UInt16, () => { il.Emit(OpCodes.Ldc_I4_0); } },
                { TypeCode.Int32, () => { il.Emit(OpCodes.Ldc_I4_0); } },
                { TypeCode.UInt32, () => { il.Emit(OpCodes.Ldc_I4_0); } },
                { TypeCode.Int64, () => { il.Emit(OpCodes.Ldc_I8, 0); } },
                { TypeCode.UInt64, () => { il.Emit(OpCodes.Ldc_I8, 0); } },
                { TypeCode.Single, () => { il.Emit(OpCodes.Ldc_R4, 0.0f); } },
                { TypeCode.Double, () => { il.Emit(OpCodes.Ldc_R8, 0.0d); } },
                { TypeCode.String, () => { il.Emit(OpCodes.Ldnull); } },
            };

            var on_stack_conversions = new Dictionary <TypeCode, Action>()
            {
                { TypeCode.Boolean, () => { il.Emit(OpCodes.Conv_Ovf_I4); } },
                { TypeCode.Int32, () => { il.Emit(OpCodes.Conv_Ovf_I4); } },
                { TypeCode.SByte, () => { il.Emit(OpCodes.Conv_Ovf_I1); } },
                { TypeCode.Byte, () => { il.Emit(OpCodes.Conv_Ovf_I1_Un); } },
                { TypeCode.Int16, () => { il.Emit(OpCodes.Conv_Ovf_I2); } },
                { TypeCode.UInt16, () => { il.Emit(OpCodes.Conv_Ovf_I2_Un); } },
                { TypeCode.UInt32, () => { il.Emit(OpCodes.Conv_Ovf_I4_Un); } },
                { TypeCode.Int64, () => { il.Emit(OpCodes.Conv_Ovf_I8); } },
                { TypeCode.UInt64, () => { il.Emit(OpCodes.Conv_Ovf_I8_Un); } },
                { TypeCode.Single, () => { il.Emit(OpCodes.Conv_R4); } },
                { TypeCode.Double, () => { il.Emit(OpCodes.Conv_R8); } },
            };

            il.BeginExceptionBlock();
            var col_index = il.DeclareLocal(typeof(int));

            int index = 0;

            foreach (var c in dr.ColumnMemberIndexMap)
            {
                il.Emit(OpCodes.Ldc_I4, index);
                il.Emit(OpCodes.Stloc, col_index.LocalIndex);

                var setMethod = c.Property.GetSetMethod();
                if (c.IsNullableType)
                {
                    var nullable_local = il.DeclareLocal(c.Property.PropertyType);
                    var underlyingType = c.UnderlyingGenericType;

                    var origin     = dr.GetFieldType(index);
                    var originType = Type.GetTypeCode(origin);

                    var nullable_constructor = c.Type.GetConstructors().First();

                    var was_not_null = il.DefineLabel();
                    var set_column   = il.DefineLabel();

                    //load up our object .. again.
                    il.Emit(OpCodes.Ldarg_1);
                    il.Emit(OpCodes.Castclass, c.Property.DeclaringType);
                    //test if it was null

                    il.Emit(OpCodes.Ldarg_0);
                    _emitInt32(il, index);
                    il.Emit(OpCodes.Callvirt, is_dbnull);
                    il.Emit(OpCodes.Brfalse_S, was_not_null);

                    //new up a nullable<t>
                    il.Emit(OpCodes.Ldloca_S, nullable_local.LocalIndex);
                    il.Emit(OpCodes.Initobj, c.Type);
                    il.Emit(OpCodes.Ldloc, nullable_local.LocalIndex);
                    il.Emit(OpCodes.Br_S, set_column);

                    //grab the value
                    il.MarkLabel(was_not_null);
                    il.Emit(OpCodes.Ldarg_0);
                    _emitInt32(il, index);

                    MethodInfo get_value = null;
                    if (type_accessors.ContainsKey(originType))
                    {
                        get_value = type_accessors[originType];
                    }
                    else if (origin == typeof(Guid))
                    {
                        get_value = get_guid_fn;
                    }
                    else
                    {
                        get_value = get_value_fn;
                    }

                    il.EmitCall(OpCodes.Callvirt, get_value, null);
                    il.Emit(OpCodes.Newobj, nullable_constructor);

                    il.MarkLabel(set_column);
                    il.EmitCall(OpCodes.Callvirt, setMethod, null);
                }
                else
                {
                    var origin          = dr.GetFieldType(index);
                    var originType      = Type.GetTypeCode(origin);
                    var destinationType = Type.GetTypeCode(c.Type);

                    var was_not_null = il.DefineLabel();
                    var set_column   = il.DefineLabel();

                    il.Emit(OpCodes.Ldarg_1);
                    il.Emit(OpCodes.Castclass, c.Property.DeclaringType);

                    if (!c.ColumnAttribute.IsPrimaryKey && c.ColumnAttribute.CanBeNull)
                    {
                        il.Emit(OpCodes.Ldarg_0);
                        _emitInt32(il, index);
                        il.Emit(OpCodes.Callvirt, is_dbnull);
                        il.Emit(OpCodes.Brfalse_S, was_not_null);

                        //new up a default(T)
                        if (defaults.ContainsKey(destinationType))
                        {
                            defaults[destinationType]();
                        }
                        else
                        {
                            var local = il.DeclareLocal(c.Property.PropertyType);
                            il.Emit(OpCodes.Ldloca_S, local.LocalIndex);
                            il.Emit(OpCodes.Initobj, c.Property.PropertyType);
                            il.Emit(OpCodes.Ldloc, local.LocalIndex);
                        }
                        il.Emit(OpCodes.Br_S, set_column);
                        il.MarkLabel(was_not_null);
                    }

                    //get the value
                    il.Emit(OpCodes.Ldarg_0);
                    _emitInt32(il, index);

                    MethodInfo get_value = null;
                    if (type_accessors.ContainsKey(originType))
                    {
                        get_value = type_accessors[originType];
                    }
                    else if (origin == typeof(Guid))
                    {
                        get_value = get_guid_fn;
                    }
                    else
                    {
                        get_value = get_value_fn;
                    }

                    il.EmitCall(OpCodes.Callvirt, get_value, null);

                    if (originType != destinationType)
                    {
                        //we need to cast ...
                        if (destinationType == TypeCode.String)
                        {
                            var to_s  = _getToStringForType(origin);
                            var local = il.DeclareLocal(origin);

                            il.Emit(OpCodes.Stloc, local.LocalIndex);
                            il.Emit(OpCodes.Ldloca_S, local.LocalIndex);
                            il.Emit(OpCodes.Call, to_s);
                        }
                        else
                        {
                            if (on_stack_conversions.ContainsKey(destinationType))
                            {
                                on_stack_conversions[destinationType]();
                            }
                            else //failsafe if we end up here, though doubtful ...
                            {
                                il.Emit(OpCodes.Newobj, c.Type);
                            }
                        }
                    }
                    else if (originType == destinationType && c.Type.Equals(typeof(Byte[])))
                    {
                        il.Emit(OpCodes.Castclass, typeof(Byte[]));
                    }

                    il.MarkLabel(set_column);
                    il.EmitCall(OpCodes.Callvirt, setMethod, null);
                }
                index++;
            }

            var endLabel = il.DefineLabel();

            il.BeginCatchBlock(typeof(Exception));
            il.Emit(OpCodes.Ldloc, col_index.LocalIndex);
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Ldarg_0);
            il.EmitCall(OpCodes.Call, idr.GetMethod("ThrowDataException"), null);
            il.EndExceptionBlock();

            il.MarkLabel(endLabel);
            il.Emit(OpCodes.Nop);
            il.Emit(OpCodes.Ret);

            return((SetInstanceValuesDelegate)dyn.CreateDelegate(typeof(SetInstanceValuesDelegate)));
        }
コード例 #9
0
        private IEnumerable <T> _slowPipeline()
        {
            var list           = new List <T>();
            var connectionName = Model.ConnectionName(_t);

            using (var cmd = Destrier.Execute.Command(connectionName))
            {
                cmd.CommandText = this.QueryBody;
                cmd.CommandType = System.Data.CommandType.Text;
                Destrier.Execute.Utility.AddParametersToCommand(_parameters, cmd, connectionName);

                using (var dr = new IndexedSqlDataReader(cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection), type: _t))
                {
                    var objectLookups = new Dictionary <Type, Dictionary <Object, Object> >();
                    var parentDict    = new Dictionary <Object, Object>();
                    objectLookups.Add(_t, parentDict);

                    while (dr.Read())
                    {
                        var newObject = (T)ReflectionHelper.GetNewObject(_t);
                        dr.DeepPopulate(newObject, objectLookups: objectLookups, thisType: _t);
                        list.Add(newObject);
                    }

                    if (_builder.ChildCollections.Any())
                    {
                        foreach (var cm in _builder.ChildCollections.Where(cm => !cm.IsLazy))
                        {
                            var root   = cm.Root;
                            var parent = cm.Parent ?? cm.Root;
                            var referencedParentPrimaryKey = cm.ReferencedProperty;

                            dr.NextResult(cm.CollectionType);

                            if (!objectLookups.ContainsKey(cm.CollectionType))
                            {
                                objectLookups.Add(cm.CollectionType, new Dictionary <Object, Object>());
                            }

                            dr.ReadIntoParentCollection(cm.CollectionType, (reader, obj) =>
                            {
                                var pkValue         = referencedParentPrimaryKey.GetValue(obj);
                                var pkValueAsString = pkValue != null ? pkValue.ToString() : null;

                                var objPrimaryKeys = Model.ColumnsPrimaryKey(cm.CollectionType);

                                object objPrimaryKeyValue = Model.InstancePrimaryKeyValue(cm.CollectionType, obj);

                                object parentObj = null;
                                objectLookups[cm.DeclaringType].TryGetValue(pkValueAsString, out parentObj);

                                if (parentObj != null)
                                {
                                    var parentCollectionProperty = cm.Property;

                                    //new up the collection if it hasn't been delcared yet.
                                    if (parentCollectionProperty.GetValue(parentObj) == null)
                                    {
                                        parentCollectionProperty.SetValue(parentObj, ReflectionHelper.GetNewObject(cm.Type));
                                    }

                                    //set up lookup for the object
                                    Dictionary <Object, Object> objLookup = null;
                                    objectLookups.TryGetValue(cm.CollectionType, out objLookup);

                                    if (objLookup != null && objPrimaryKeyValue != null)
                                    {
                                        if (!objLookup.ContainsKey(objPrimaryKeyValue))
                                        {
                                            objLookup.Add(objPrimaryKeyValue, obj);
                                        }
                                        else
                                        {
                                            obj = objLookup[objPrimaryKeyValue];
                                        }
                                    }

                                    var collection = parentCollectionProperty.GetValue(parentObj);
                                    ((System.Collections.IList)collection).Add(obj);
                                }
                            }, populateFullResults: true, advanceToNextResultAfter: false, objectLookups: objectLookups);
                        }
                    }
                }
            }
            return(list);
        }