Esempio n. 1
0
        private Func <DbDataReader, TResult> GetMaterializer <TResult>(DbDataReader reader) where TResult : class, new()
        {
            var root            = new RootWithBindings(Expression.New(typeof(TResult)), String.Empty);
            var readerParameter = Expression.Parameter(typeof(DbDataReader), "reader");
            var readerIndexer   = typeof(DbDataReader).GetMethod("get_Item", new[] { typeof(Int32) });

            PropertyInfo propertyInfo;

            for (var column = 0; column < reader.FieldCount; column++)
            {
                var members = reader.GetName(column).Split('.');

                var currentRoot = root;

                for (var index = 0; index < members.Length - 1; index++)
                {
                    var member = members[index];
                    propertyInfo = currentRoot.Root.Type.GetProperty(member);

                    var newRoot = currentRoot.ObjectBindings.FirstOrDefault(b => b.Value.Name == member).Value;
                    if (newRoot == null)
                    {
                        if (propertyInfo.PropertyType.GetConstructor(Type.EmptyTypes) == null)
                        {
                            throw new MissingMemberException("No public parameterless constructor found on '" +
                                                             propertyInfo.PropertyType.FullName + "' type.");
                        }

                        // Creating new descendent object
                        newRoot = new RootWithBindings(Expression.New(propertyInfo.PropertyType), member);
                        currentRoot.ObjectBindings.Add(propertyInfo, newRoot);
                    }
                    currentRoot = newRoot;
                }

                // Assigning direct property on last descendent object
                propertyInfo = currentRoot.Root.Type.GetProperty(members[members.Length - 1]);
                if (reader[column].GetType() != propertyInfo.PropertyType &&
                    reader[column].GetType() != typeof(DBNull))
                {
                    throw new InvalidCastException("Property '" + typeof(TResult).Name + "." + reader.GetName(column) + "' is of type '" +
                                                   propertyInfo.PropertyType + "' when database returned '" + reader[column].GetType() + "' value.");
                }
                var valueExpression = Expression.Call(readerParameter, readerIndexer, Expression.Constant(column));

                currentRoot.MemberBindings.Add(Expression.Bind(propertyInfo,
                                                               Expression.Convert(
                                                                   Expression.Condition(Expression.Equal(valueExpression, Expression.Constant(DBNull.Value)),
                                                                                        Expression.Constant(null), valueExpression),
                                                                   propertyInfo.PropertyType)
                                                               )
                                               );
            }

            return(Expression.Lambda <Func <DbDataReader, TResult> >(BuildTree(root), readerParameter).Compile());
        }
Esempio n. 2
0
        private Expression BuildTree(RootWithBindings root)
        {
            var bindings = new List <MemberBinding>(root.MemberBindings);

            foreach (var binding in root.ObjectBindings)
            {
                bindings.Add(Expression.Bind(binding.Key, BuildTree(binding.Value)));
            }
            return(Expression.MemberInit(root.Root, bindings));
        }