Example #1
0
        public async Task <int> InsertAsync <T>(List <T> entityList) where T : class, IEntity, new()
        {
            var entityInfo = MyEntityContainer.Get(typeof(T));

            var sqlBuilder = new SqlServerBuilder();
            var sql        = sqlBuilder.Insert(entityInfo);

            var count = 0;

            using (var conn = new SqlConnection(_connectionString))
            {
                conn.Open();
                using (var trans = conn.BeginTransaction())
                {
                    try
                    {
                        foreach (var entity in entityList)
                        {
                            using (var command = new SqlCommand(sql, conn, trans))
                            {
                                var parameters = new MyDbParameters();
                                parameters.Add(entity);
                                command.Parameters.AddRange(parameters.Parameters);
                                var obj = await command.ExecuteScalarAsync();

                                if (obj != DBNull.Value)
                                {
                                    entity.Id = Convert.ToInt32(obj);
                                    count++;
                                }
                            }
                        }
                        trans.Commit();
                    }
                    catch
                    {
                        trans.Rollback();
                        count = 0;
                    }
                }
            }

            return(count);
        }
Example #2
0
        public async Task <int> UpdateAsync <T>(Expression <Func <T, bool> > expression, DbKvs kvs)
        {
            var entityInfo        = MyEntityContainer.Get(typeof(T));
            var setProperties     = kvs.Where(kv => kv.Key != "Id").Select(kv => kv.Key);
            var includeProperties = entityInfo.Properties.Where(p => setProperties.Contains(p.Name)).ToList();

            if (includeProperties.Count == 0)
            {
                return(0);
            }

            string sql;
            List <SqlParameter> parameters;

            if (expression == null)
            {
                sql =
                    $"UPDATE [{entityInfo.TableName}] SET {string.Join(",", includeProperties.Select(p => $"{p.FieldName}=@{p.Name}"))} WHERE Id=@Id";
                parameters = kvs.ToSqlParameters();
            }
            else
            {
                var resolver = new EditConditionResolver <T>(entityInfo);
                var result   = resolver.Resolve(expression.Body);
                var where = result.Condition;
                var whereParameters = result.Parameters;

                parameters = kvs.ToSqlParameters();
                parameters.AddRange(whereParameters.Parameters);

                where = string.IsNullOrWhiteSpace(where) ? "1=1" : where;

                sql =
                    $"UPDATE [{entityInfo.TableName}] SET {string.Join(",", includeProperties.Select(p => $"{p.FieldName}=@{p.Name}"))} WHERE {where}";
            }

            using (var conn = new SqlConnection(_connectionString))
            {
                conn.Open();
                var command = new SqlCommand(sql, conn);
                command.Parameters.AddRange(parameters.ToArray());
                return(await command.ExecuteNonQueryAsync());
            }
        }
        public void ResolveMemberAccessExpression(MemberExpression expression)
        {
            if (expression == null)
            {
                throw new ArgumentNullException(nameof(expression));
            }

            var rootType = expression.RootExpressionType(out var parameterStack);

            if (rootType == ExpressionType.Parameter)
            {
                if (parameterStack.Count == 2)
                {
                    // 调用了导航属性
                    var propertyName      = parameterStack.Pop();
                    var propertyFieldName = parameterStack.Pop();

                    JoinPropertyList.Add(propertyName);

                    var prop             = _master.Properties.Single(p => p.Name == propertyName);
                    var propertyEntity   = MyEntityContainer.Get(prop.PropertyInfo.PropertyType);
                    var propertyProperty = propertyEntity.Properties.Single(p => p.Name == propertyFieldName);

                    _stringStack.Push($"[{propertyName}].[{propertyProperty.FieldName}]");
                }
                else if (parameterStack.Count == 1)
                {
                    var propertyName = parameterStack.Pop();
                    var propInfo     = _master.Properties.Single(p => p.Name == propertyName);
                    _stringStack.Push($"[{_master.TableName}].[{propInfo.FieldName}]");
                }
                else
                {
                    throw new ArgumentException("尚未支持大于2层属性调用。如 student.Clazz.School.Id>10,请使用类似 student.Clazz.SchoolId > 0 替代");
                }
            }
            else
            {
                var obj           = ResolveValue(expression.GetValue());
                var parameterName = $"{_prefix}__p_{_parameterIndex++}";
                _parameters.Add(new KeyValuePair <string, object>(parameterName, obj));
                _stringStack.Push($" {parameterName} ");
            }
        }
Example #4
0
        /// <summary>
        /// 批量创建实体,注意此方法效率不高
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entityList">实体列表</param>
        /// <returns>受影响的记录数</returns>
        public int Insert <T>(List <T> entityList) where T : class, IEntity, new()
        {
            var entityInfo = MyEntityContainer.Get(typeof(T));

            var sqlBuilder = new SqlServerSqlBuilder();
            var sql        = sqlBuilder.Insert(entityInfo);

            var count = 0;

            using (var conn = new SqlConnection(_connectionString))
            {
                conn.Open();
                using (var trans = conn.BeginTransaction())
                {
                    try
                    {
                        foreach (var entity in entityList)
                        {
                            using (var command = new SqlCommand(sql, conn, trans))
                            {
                                command.Parameters.AddRange(entityInfo
                                                            .Properties
                                                            .Where(p => !p.InsertIgnore)
                                                            .Select(p => new SqlParameter($"{_prefix}{p.Name}",
                                                                                          ResolveParameterValue(p.PropertyInfo.GetValue(entity))))
                                                            .ToArray());
                                var result = command.ExecuteScalar().ToString();
                                entity.Id = Convert.ToInt32(string.IsNullOrWhiteSpace(result) ? "0" : result);
                                count++;
                            }
                        }
                        trans.Commit();
                    }
                    catch
                    {
                        trans.Rollback();
                        count = 0;
                    }
                }
            }

            return(count);
        }
Example #5
0
        /// <summary>
        /// 如果不满足条件则创建一个实体,
        /// 如限制用户名不能重复 InsertIfNotExist(user, u => u.Name == user.Name)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity">要创建的实体</param>
        /// <param name="where">条件</param>
        /// <returns>新生成记录的ID,若失败返回0</returns>
        public int InsertIfNotExists <T>(T entity, Expression <Func <T, bool> > where) where T : class, IEntity, new()
        {
            if (where == null)
            {
                return(Insert(entity));
            }
            else
            {
                var entityInfo = MyEntityContainer.Get(typeof(T));
                //var whereExpressionVisitor = new WhereExpressionVisitor<T>(entityInfo);
                //whereExpressionVisitor.Visit(where);
                //var condition = whereExpressionVisitor.GetCondition();
                //var parameters = whereExpressionVisitor.GetParameters().ToSqlParameters();

                var resolver = new ConditionResolver(entityInfo);
                resolver.Resolve(where.Body);
                var condition  = resolver.GetCondition();
                var parameters = resolver.GetParameters().ToSqlParameters();

                condition = string.IsNullOrWhiteSpace(condition) ? "1=1" : condition;

                var sqlBuilder = new SqlServerSqlBuilder();
                var sql        = sqlBuilder.InsertIfNotExists(entityInfo, condition);

                parameters.AddRange(
                    entityInfo
                    .Properties
                    .Where(p => !p.InsertIgnore)
                    .Select(p => new SqlParameter($"{_prefix}{p.Name}",
                                                  ResolveParameterValue(p.PropertyInfo.GetValue(entity)))));
                var command = new SqlCommand(sql);
                command.Parameters.AddRange(parameters.ToArray());

                using (var conn = new SqlConnection(_connectionString))
                {
                    conn.Open();
                    command.Connection = conn;
                    var result = command.ExecuteScalar().ToString();
                    entity.Id = Convert.ToInt32(string.IsNullOrWhiteSpace(result) ? "0" : result);
                    return(entity.Id);
                }
            }
        }
Example #6
0
        /// <summary>
        /// 更新多个实体
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entityList">要更新的实体列表</param>
        /// <returns>受影响的记录数</returns>
        public int Update <T>(List <T> entityList) where T : class, IEntity, new()
        {
            var entityInfo = MyEntityContainer.Get(typeof(T));

            var sqlBuilder = new SqlServerSqlBuilder();
            var sql        = sqlBuilder.Update(entityInfo, "");

            var count = 0;

            using (var conn = new SqlConnection(_connectionString))
            {
                conn.Open();
                using (var trans = conn.BeginTransaction())
                {
                    try
                    {
                        foreach (var entity in entityList)
                        {
                            using (var command = new SqlCommand(sql, conn, trans))
                            {
                                command.Parameters.AddRange(entityInfo
                                                            .Properties
                                                            .Where(p => !p.UpdateIgnore || p.IsKey)
                                                            .Select(p => new SqlParameter($"{_prefix}{p.Name}",
                                                                                          ResolveParameterValue(p.PropertyInfo.GetValue(entity))))
                                                            .ToArray());
                                count += command.ExecuteNonQuery();
                            }
                        }
                        trans.Commit();
                    }
                    catch (Exception)
                    {
                        trans.Rollback();
                        count = 0;
                    }
                }
            }

            return(count);
        }
        public string GetFieldFullName(Stack <string> stack)
        {
            if (stack.Count == 1)
            {
                var fieldName = stack.Pop();
                var property  = _master.Properties.Single(p => p.Name == fieldName);
                return($"[{_master.TableName}].[{property.FieldName}]");
            }
            else if (stack.Count == 2)
            {
                var propertyName = stack.Pop();
                var fieldName    = stack.Pop();

                var property       = _master.Properties.Single(p => p.Name == propertyName);
                var propertyEntity = MyEntityContainer.Get(property.PropertyInfo.PropertyType);
                var field          = propertyEntity.Properties.Single(p => p.Name == fieldName);

                return($"[{propertyName}].[{field.FieldName}]");
            }
            return(string.Empty);
        }
Example #8
0
        public async Task <int> GetCountAsync <T>(Expression <Func <T, bool> > expression = null) where T : class, IEntity, new()
        {
            var entityInfo = MyEntityContainer.Get(typeof(T));

            if (expression == null)
            {
                var sql = $"SELECT COUNT(0) FROM [{entityInfo.TableName}]";
                using (var conn = new SqlConnection(_connectionString))
                {
                    conn.Open();
                    var command = new SqlCommand(sql, conn);
                    return((int)command.ExecuteScalar());
                }
            }
            else
            {
                var resolver   = new EditConditionResolver <T>(entityInfo);
                var result     = resolver.Resolve(expression.Body);
                var condition  = result.Condition;
                var parameters = result.Parameters;

                condition = string.IsNullOrWhiteSpace(condition) ? "1=1" : condition;

                var sql = $"SELECT COUNT(0) FROM [{entityInfo.TableName}] WHERE [{condition}]";
                using (var conn = new SqlConnection(_connectionString))
                {
                    conn.Open();
                    var command = new SqlCommand(sql, conn);
                    command.Parameters.AddRange(parameters.Parameters);
                    var obj = await command.ExecuteScalarAsync();

                    if (obj == null)
                    {
                        return(0);
                    }

                    return((int)obj);
                }
            }
        }
Example #9
0
        /// <summary>
        /// 如果不存在,则更新
        /// 如:UpdateIfNotExists(user, u=>u.Name == user.Name && u.Id != user.Id)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <param name="where"></param>
        /// <returns>受影响的记录数</returns>
        public int UpdateIfNotExits <T>(T entity, Expression <Func <T, bool> > where)
        {
            var entityInfo = MyEntityContainer.Get(typeof(T));

            //var whereExpressionVisitor = new WhereExpressionVisitor<T>(entityInfo);
            //whereExpressionVisitor.Visit(where);
            //var condition = whereExpressionVisitor.GetCondition();
            //var parameters = whereExpressionVisitor.GetParameters().ToSqlParameters();

            var resolver = new ConditionResolver(entityInfo);

            resolver.Resolve(where.Body);
            var condition  = resolver.GetCondition();
            var parameters = resolver.GetParameters().ToSqlParameters();

            condition = string.IsNullOrWhiteSpace(condition) ? "1=1" : condition;

            var sqlBuilder = new SqlServerSqlBuilder();
            var sql        = sqlBuilder.Update(entityInfo, "");

            sql += $" AND NOT EXISTS (SELECT 1 FROM [{entityInfo.TableName}] WHERE {condition})";

            parameters.AddRange(
                entityInfo
                .Properties
                .Where(p => !p.UpdateIgnore || p.IsKey)
                .Select(p => new SqlParameter($"{_prefix}{p.Name}",
                                              ResolveParameterValue(p.PropertyInfo.GetValue(entity)))));

            var command = new SqlCommand(sql);

            command.Parameters.AddRange(parameters.ToArray());

            using (var conn = new SqlConnection(_connectionString))
            {
                conn.Open();
                command.Connection = conn;
                return(command.ExecuteNonQuery());
            }
        }
Example #10
0
        public async Task <int> UpdateAsync <T>(T entity) where T : class, IEntity, new()
        {
            var entityInfo = MyEntityContainer.Get(typeof(T));

            var sqlBuilder = new SqlServerBuilder();
            var sql        = sqlBuilder.Update(entityInfo, "");

            var parameters = new MyDbParameters();

            parameters.Add(entity);

            var command = new SqlCommand(sql);

            command.Parameters.AddRange(parameters.Parameters);

            using (var conn = new SqlConnection(_connectionString))
            {
                conn.Open();
                command.Connection = conn;
                return(await command.ExecuteNonQueryAsync());
            }
        }
Example #11
0
        public int GetCount <T>(Expression <Func <T, bool> > expression = null) where T : class, IEntity, new()
        {
            var entityInfo = MyEntityContainer.Get(typeof(T));

            if (expression == null)
            {
                var sql = $"SELECT COUNT(0) FROM [{entityInfo.TableName}]";
                using (var conn = new SqlConnection(_connectionString))
                {
                    conn.Open();
                    var command = new SqlCommand(sql, conn);
                    return((int)command.ExecuteScalar());
                }
            }
            else
            {
                //var whereExpressionVisitor = new WhereExpressionVisitor<T>();
                //whereExpressionVisitor.Visit(expression);
                //var condition = whereExpressionVisitor.GetCondition();
                //var parameters = whereExpressionVisitor.GetParameters().ToSqlParameters();

                var resolver = new ConditionResolver(entityInfo);
                resolver.Resolve(expression.Body);
                var condition  = resolver.GetCondition();
                var parameters = resolver.GetParameters().ToSqlParameters();

                condition = string.IsNullOrWhiteSpace(condition) ? "1=1" : condition;

                var sql = $"SELECT COUNT(0) FROM [{entityInfo.TableName}] WHERE [{condition}]";
                using (var conn = new SqlConnection(_connectionString))
                {
                    conn.Open();
                    var command = new SqlCommand(sql, conn);
                    command.Parameters.AddRange(parameters.ToArray());
                    return((int)command.ExecuteScalar());
                }
            }
        }
Example #12
0
        /// <summary>
        /// 更新多个实体
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entityList">要更新的实体列表</param>
        /// <returns>受影响的记录数</returns>
        public int Update <T>(List <T> entityList) where T : class, IEntity, new()
        {
            var entityInfo = MyEntityContainer.Get(typeof(T));

            var sqlBuilder = new SqlServerBuilder();
            var sql        = sqlBuilder.Update(entityInfo, "");

            var count = 0;

            using (var conn = new SqlConnection(_connectionString))
            {
                conn.Open();
                using (var trans = conn.BeginTransaction())
                {
                    try
                    {
                        foreach (var entity in entityList)
                        {
                            using (var command = new SqlCommand(sql, conn, trans))
                            {
                                var param = new MyDbParameters();
                                param.Add(entity);
                                command.Parameters.AddRange(param.Parameters);
                                count += command.ExecuteNonQuery();
                            }
                        }
                        trans.Commit();
                    }
                    catch (Exception)
                    {
                        trans.Rollback();
                        count = 0;
                    }
                }
            }

            return(count);
        }
Example #13
0
        /// <summary>
        /// 根据条件删除记录,如果支持软删除并且非强制删除,则更新IsDel字段为true,否则,删除记录
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="expression">条件,注意不支持导航属性及其子属性</param>
        /// <param name="isForce">是否强制删除</param>
        /// <returns>受影响的记录数</returns>
        public int Delete <T>(Expression <Func <T, bool> > expression, bool isForce) where T : IEntity
        {
            var entityInfo = MyEntityContainer.Get(typeof(T));

            //var whereExpressionVisitor = new WhereExpressionVisitor<T>();
            //whereExpressionVisitor.Visit(expression);
            //var where = whereExpressionVisitor.GetCondition();
            //var whereParameters = whereExpressionVisitor.GetParameters().ToSqlParameters();

            var resolver = new ConditionResolver(entityInfo);

            resolver.Resolve(expression.Body);
            var condition  = resolver.GetCondition();
            var parameters = resolver.GetParameters().ToSqlParameters();

            condition = string.IsNullOrWhiteSpace(condition) ? "1=1" : condition;
            string sql;

            if (isForce || !entityInfo.IsSoftDelete)
            {
                sql =
                    $"DELETE [{entityInfo.TableName}] WHERE {condition}";
            }
            else
            {
                sql =
                    $"UPDATE [{entityInfo.TableName}] SET IsDel=1 WHERE {condition}";
            }

            using (var conn = new SqlConnection(_connectionString))
            {
                conn.Open();
                var command = new SqlCommand(sql, conn);
                command.Parameters.AddRange(parameters.ToArray());
                return(command.ExecuteNonQuery());
            }
        }
Example #14
0
        public async Task <int> InsertIfNotExistsAsync <T>(T entity, Expression <Func <T, bool> > where) where T : class, IEntity, new()
        {
            if (where == null)
            {
                return(Insert(entity));
            }

            var entityInfo = MyEntityContainer.Get(typeof(T));
            var resolver   = new EditConditionResolver <T>(entityInfo);
            var result     = resolver.Resolve(@where.Body);
            var condition  = result.Condition;
            var parameters = result.Parameters;

            parameters.Add(entity);

            condition = string.IsNullOrWhiteSpace(condition) ? "1=1" : condition;

            var sqlBuilder = new SqlServerBuilder();
            var sql        = sqlBuilder.InsertIfNotExists(entityInfo, condition);
            var command    = new SqlCommand(sql);

            command.Parameters.AddRange(parameters.Parameters);

            using (var conn = new SqlConnection(_connectionString))
            {
                conn.Open();
                command.Connection = conn;
                var obj = await command.ExecuteScalarAsync();

                if (obj != DBNull.Value)
                {
                    entity.Id = Convert.ToInt32(obj);
                }
                return(entity.Id);
            }
        }
Example #15
0
        public async Task <int> UpdateAsync <T>(int id, DbKvs kvs)
        {
            var entityInfo        = MyEntityContainer.Get(typeof(T));
            var setProperties     = kvs.Where(kv => kv.Key != "Id").Select(kv => kv.Key);
            var includeProperties = entityInfo.Properties.Where(p => setProperties.Contains(p.Name)).ToList();

            if (includeProperties.Count == 0)
            {
                return(0);
            }

            var sql =
                $"UPDATE [{entityInfo.TableName}] SET {string.Join(",", includeProperties.Select(p => $"{p.FieldName}=@{p.Name}"))} WHERE Id=@Id";
            var parameters = kvs.ToSqlParameters();

            parameters.Add(new SqlParameter("@Id", id));
            using (var conn = new SqlConnection(_connectionString))
            {
                conn.Open();
                var command = new SqlCommand(sql, conn);
                command.Parameters.AddRange(parameters.ToArray());
                return(await command.ExecuteNonQueryAsync());
            }
        }
Example #16
0
        /// <summary>
        /// 更新一个实体
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity">要更新的实体</param>
        /// <returns>受影响的记录数</returns>
        public int Update <T>(T entity) where T : class, IEntity, new()
        {
            var entityInfo = MyEntityContainer.Get(typeof(T));

            var sqlBuilder = new SqlServerSqlBuilder();
            var sql        = sqlBuilder.Update(entityInfo, "");

            var parameterList = entityInfo
                                .Properties
                                .Where(p => !p.UpdateIgnore || p.IsKey)
                                .Select(p => new SqlParameter($"{_prefix}{p.Name}",
                                                              ResolveParameterValue(p.PropertyInfo.GetValue(entity))));

            var command = new SqlCommand(sql);

            command.Parameters.AddRange(parameterList.ToArray());

            using (var conn = new SqlConnection(_connectionString))
            {
                conn.Open();
                command.Connection = conn;
                return(command.ExecuteNonQuery());
            }
        }
Example #17
0
 public void Add(object obj)
 {
     if (obj is MyDbParameter parameter)
     {
         _dict.Add(parameter);
     }
     else if (obj is IEntity)
     {
         var entityInfo = MyEntityContainer.Get(obj.GetType());
         foreach (var property in entityInfo.Properties.Where(p => p.IsMap))
         {
             Add(_prefix + property.Name, property.PropertyInfo.GetValue(obj));
         }
     }
     else
     {
         var properties = obj.GetType().GetProperties();
         foreach (var property in properties.Where(p => p.PropertyType.IsValueType ||
                                                   p.PropertyType == typeof(string)))
         {
             Add(_prefix + property.Name, ResolveParameterValue(property.GetValue(obj)));
         }
     }
 }
Example #18
0
        static void Main(string[] args)
        {
            //var dt = DateTime.Today;
            //var isActive = true;
            //Expression<Func<Student, bool>> expr = s => (s.CreateAt > dt || s.UpdateAt > dt) &&
            //                                            s.IsDel &&
            //                                            true &&
            //                                            isActive &&
            //                                            s.School.SchoolName.Contains("测试") &&
            //                                            s.CreateAt < s.UpdateAt &&
            //                                            s.Birthday == null;
            ////Expression<Func<Student, bool>> expr = s => isActive && s.Birthday != null && true;

            //var resolver = new ConditionResolver(MyEntityContainer.Get(typeof(Student)));

            //resolver.Resolve(expr.Body);
            //Console.WriteLine(resolver.GetCondition());

            //var parameters = resolver.GetParameters();
            //foreach (var parameter in parameters)
            //{
            //    Console.WriteLine($"{parameter.Key} : {parameter.Value}");
            //}


            //var search = LinqExtensions.False<Student>();
            //search = search.And(s => s.CreateAt > dt || s.UpdateAt > dt);
            //search = search.And(s => !s.IsDel);
            //search = search.And(s => s.School.SchoolName.Contains("测试"));

            //var visitor = new WhereExpressionVisitor<Student>();
            //visitor.Visit(expr);

            //Console.WriteLine(visitor.GetCondition());

            //var parameters = visitor.GetParameters();
            //foreach (var parameter in parameters)
            //{
            //    Console.WriteLine($"{parameter.Key} = {parameter.Value}");
            //}

            //Console.WriteLine("======================");

            //var visitor2 = new WhereExpressionVisitor<Student>();
            //visitor2.Visit(search);

            //Console.WriteLine(visitor2.GetCondition());
            //var parameters2 = visitor2.GetParameters();
            //foreach (var parameter in parameters2)
            //{
            //    Console.WriteLine($"{parameter.Key} = {parameter.Value}");
            //}

            Expression <Func <Student, object> > expr = s => new { s.StudentName, s.FKSchoolId };

            Expression <Func <Student, object> > expr2 = s => s.StudentName;

            var visitor1 = new ObjectExpressionVisitor(MyEntityContainer.Get(typeof(Student)));

            visitor1.Visit(expr);

            var visitor2 = new ObjectExpressionVisitor(MyEntityContainer.Get(typeof(Student)));

            visitor1.Visit(expr2);

            var kvs1 = visitor1.GetPropertyList();

            foreach (var kv in kvs1)
            {
                Console.WriteLine($"{kv.Key}-{kv.Value}");
            }

            var kvs2 = visitor2.GetPropertyList();

            foreach (var kv in kvs2)
            {
                Console.WriteLine($"{kv.Key}-{kv.Value}");
            }

            var student = new Student();

            var db = MyDb.New("").Update <Student>(student,
                                                   s => new { s.FKSchoolId, s.StudentName });

            Console.Read();
        }
Example #19
0
 public SelectConditionResolver(string prefix = "@")
 {
     _entity = MyEntityContainer.Get(typeof(T));
     _prefix = prefix;
 }
Example #20
0
        public Func <SqlDataReader, T> GetFunc(SqlDataReader sdr)
        {
            if (!Dict.TryGetValue(Key, out var func))
            {
                var sdrParameter   = Expression.Parameter(typeof(SqlDataReader), "sdr");
                var memberBindings = new List <MemberBinding>();
                var subMemberMaps  = new Dictionary <string, List <IncludePropertySdrMap> >();
                foreach (var include in Includes)
                {
                    subMemberMaps.Add(include, new List <IncludePropertySdrMap>());
                }

                for (var i = 0; i < sdr.FieldCount; i++)
                {
                    var fieldName  = sdr.GetName(i);
                    var fieldNames = fieldName.Split('_');

                    if (fieldNames.Length == 1)
                    {
                        var property = Master.Properties.SingleOrDefault(p => p.Name == fieldName);
                        if (property != null)
                        {
                            var methodName = GetSdrMethodName(property.PropertyInfo.PropertyType);
                            var methodCall = Expression.Call(sdrParameter,
                                                             typeof(SqlDataReader).GetMethod(methodName) ?? throw new InvalidOperationException(),
                                                             Expression.Constant(i));

                            Expression setValueExpression;
                            if (property.PropertyInfo.PropertyType.IsGenericType &&
                                property.PropertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(Nullable <>))
                            {
                                setValueExpression = Expression.Convert(methodCall, property.PropertyInfo.PropertyType);
                            }
                            else
                            {
                                setValueExpression = methodCall;
                            }

                            //memberBindings.Add(Expression.Bind(property.PropertyInfo, methodCall));
                            memberBindings.Add(
                                Expression.Bind(
                                    property.PropertyInfo,
                                    Expression.Condition(
                                        Expression.TypeIs(
                                            Expression.Call(
                                                sdrParameter,
                                                typeof(SqlDataReader).GetMethod("get_Item", new[] { typeof(int) }) ??
                                                throw new InvalidOperationException(),
                                                Expression.Constant(i)),
                                            typeof(DBNull)
                                            ),
                                        Expression.Default(property.PropertyInfo.PropertyType),
                                        setValueExpression
                                        )
                                    )
                                );
                        }
                    }
                    else
                    {
                        if (subMemberMaps.TryGetValue(fieldNames[0], out var list))
                        {
                            list.Add(new IncludePropertySdrMap {
                                PropertyName = fieldNames[1], Index = i
                            });
                        }
                    }
                }

                foreach (var include in subMemberMaps)
                {
                    var prop = Master.Properties.SingleOrDefault(p => p.Name == include.Key);
                    if (prop != null)
                    {
                        var subEntityInfo  = MyEntityContainer.Get(prop.PropertyInfo.PropertyType);
                        var subBindingList = new List <MemberBinding>();
                        foreach (var subProperty in subEntityInfo.Properties.Where(p => p.IsMap))
                        {
                            var mapper = include.Value.SingleOrDefault(v => v.PropertyName == subProperty.Name);
                            if (mapper != null)
                            {
                                var methodName = GetSdrMethodName(subProperty.PropertyInfo.PropertyType);
                                var methodCall = Expression.Call(
                                    sdrParameter,
                                    typeof(SqlDataReader).GetMethod(methodName) ?? throw new InvalidOperationException(),
                                    Expression.Constant(mapper.Index));

                                Expression setValueExpression;
                                if (subProperty.PropertyInfo.PropertyType.IsGenericType &&
                                    subProperty.PropertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(Nullable <>))
                                {
                                    setValueExpression = Expression.Convert(methodCall, subProperty.PropertyInfo.PropertyType);
                                }
                                else
                                {
                                    setValueExpression = methodCall;
                                }

                                subBindingList.Add(
                                    Expression.Bind(
                                        subProperty.PropertyInfo,
                                        Expression.Condition(
                                            Expression.TypeIs(
                                                Expression.Call(
                                                    sdrParameter,
                                                    typeof(SqlDataReader).GetMethod("get_Item", new[] { typeof(int) }) ?? throw new InvalidOperationException(),
                                                    Expression.Constant(mapper.Index)),
                                                typeof(DBNull)
                                                ),
                                            Expression.Default(subProperty.PropertyInfo.PropertyType),
                                            setValueExpression
                                            )
                                        )
                                    );
                            }
                        }

                        var subInitExpression = Expression.MemberInit(Expression.New(prop.PropertyInfo.PropertyType),
                                                                      subBindingList);
                        memberBindings.Add(Expression.Bind(prop.PropertyInfo, subInitExpression));
                    }
                }

                var initExpression = Expression.MemberInit(Expression.New(typeof(T)), memberBindings);
                func = Expression.Lambda <Func <SqlDataReader, T> >(initExpression, sdrParameter).Compile();
                Dict.Add(Key, func);
            }
            else
            {
                Console.WriteLine("应用了缓存");
            }
            return(func);
        }
Example #21
0
 // 构造方法
 public MyQueryable(string connectionString)
 {
     _masterEntity     = MyEntityContainer.Get(typeof(T));
     _connectionString = connectionString;
 }
Example #22
0
 public WhereExpressionVisitor(string prefix = "@")
 {
     _master = MyEntityContainer.Get(typeof(T));
     _prefix = prefix;
 }
Example #23
0
 protected BaseConditionResolver(string prefix = "@")
 {
     Entity  = MyEntityContainer.Get(typeof(T));
     _prefix = prefix;
 }