示例#1
0
        /// <summary>
        /// 通过实体类型获取实体信息
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public EntityInfo GetEntity(Type type)
        {
            EntityInfo entityInfo = null;

            if (!_entityInfos.TryGetValue(type, out entityInfo))
            {
                lock (_entityLocker)
                {
                    entityInfo           = new EntityInfo();
                    entityInfo.TableName = ExpressionUtil.GetEntityTableName(type);
                    if (string.IsNullOrWhiteSpace(entityInfo.TableName))
                    {
                        throw new Exception("实体必须标明TableAttribute");
                    }
                    entityInfo.EntityType = type;

                    var pis = ExpressionReflector.GetProperties(type).Values;
                    foreach (var property in pis)
                    {
                        var foreignKeyAttr = AttributeHelper.GetAttribute <ForeignKeyAttribute>(property);
                        if (foreignKeyAttr != null)
                        {
                            entityInfo.ForeignKeys.Add(property);
                        }
                        entityInfo.Properties.Add(property);
                    }

                    _entityInfos.Add(type, entityInfo);
                }
            }

            return(entityInfo);
        }
示例#2
0
        protected override Expression VisitLambda <T>(Expression <T> node)
        {
            if (node.Body is NewExpression)
            {
                //此处一般是在Select方法中new了匿名对象,例如users.Select(x=>new {x.Id})
                return(base.VisitLambda <T>(node));
            }

            //此处一般是在Select方法中直接选择了参数,例如users.Select(x=>x),这种情况下直接把x的所有列转换出来
            var properties = ExpressionReflector.GetProperties(node.Body.Type).Values;

            foreach (var item in properties)
            {
                if (!ExpressionUtil.IsEntityPropertyType(item.PropertyType))
                {
                    continue;
                    ////是否.Net自带的String、DateTime,如果不是则跳过
                    //if (!((item.PropertyType.FullName == "System.String" || item.PropertyType.FullName == "System.DateTime") && item.PropertyType.Assembly.GlobalAssemblyCache))
                    //{
                    //    continue;
                    //}
                    ////是否可空,如果不是则跳过
                    //var type = Nullable.GetUnderlyingType(item.PropertyType);
                    //if (type == null)
                    //{
                    //    continue;
                    //}
                }
                _columnInfos.Add(item.Name, new KeyValuePair <string, string>(_masterTableName, item.Name));
            }
            return(node);
        }
示例#3
0
        /// <summary>
        /// 从指定的参数列表中查找对应的name的表达式的父表达式
        /// </summary>
        /// <param name="args"></param>
        /// <param name="name"></param>
        /// <returns>可能是MemberExpression和ParameterExpression</returns>
        Expression FindArgument(IEnumerable <Expression> args, MemberInfo memberInfo)
        {
            string           name = memberInfo.Name;
            Type             type = ExpressionUtil.GetMemberType(memberInfo);
            MemberExpression temp = null;

            foreach (Expression _arg in args)
            {
                //Expression target = null;
                if (_arg is ParameterExpression)
                {
                    throw new Exception("Select子句中的匿名类不允许存在直接使用参数的表达式,例如x=>new {x}");
                }
                var arg = (MemberExpression)_arg;
                if (arg.Member.Name == name && ExpressionUtil.GetMemberType(arg.Member) == type)
                {
                    return(arg.Expression);
                }
                temp = (MemberExpression)arg.Expression;
                while (true)
                {
                    if (temp.Expression is ParameterExpression)
                    {
                        break;
                    }
                    temp = (MemberExpression)temp.Expression;
                    if (temp.Member.Name == name && ExpressionUtil.GetMemberType(temp.Member) == type)
                    {
                        return(temp.Expression);
                    }
                }
            }
            return(null);
        }
示例#4
0
        protected override Expression VisitMember(MemberExpression node)
        {
            if (node.Expression is ParameterExpression)
            {
                //访问到了根节点了
                if (_properties.Count <= 0)
                {
                    _columnInfos.Add(node.Member.Name, new KeyValuePair <string, string>(_masterTableName, node.Member.Name));
                }
                else
                {
                    Type type = node.Type;
                    if (type.IsGenericType)
                    {
                        type = Nullable.GetUnderlyingType(type);
                    }
                    if (!(type.FullName == "System.DateTime" && type.Assembly.GlobalAssemblyCache))
                    {
                        throw new ArgumentException("Select子句中多个属性访问的表达式时,若属性名为Date,则只能支持访问DateTime类型的实体,例如x.Time.Date");
                    }

                    NeedWrapSelect = true;
                    _columnInfos.Add(node.Member.Name, new KeyValuePair <string, string>(_masterTableName, node.Member.Name));
                    _columnMethods.Add(new KeyValuePair <string, string>(_masterTableName, node.Member.Name), "CONVERT(NVARCHAR(20),{0},101)");
                    if (!_tableInfos.ContainsKey(_masterTableName))
                    {
                        _tableInfos.Add(_masterTableName, ExpressionUtil.GenerateRandomTableAlias());
                    }
                    _properties.Clear();
                }
            }
            else
            {
                //不是根节点,取出Member属性用于计算值
                PropertyInfo propertyInfo = (PropertyInfo)node.Member;
                if (propertyInfo.Name == "Value")
                {
                    propertyInfo = (PropertyInfo)((MemberExpression)node.Expression).Member;
                    //跳过可空类型
                    if (!propertyInfo.PropertyType.IsGenericType)
                    {
                        throw new ArgumentException("在Select子句中,若使用了多个属性访问的表达式并且属性名为Value,则该表达式只允许为访问Nullable<T>的表达式,例如如果实体的Time为DateTime?,则可以写为x.Time.Value");
                    }
                    else
                    {
                        return(base.VisitMember(node));
                    }
                }
                NeedWrapSelect = true;
                _properties.Push(propertyInfo);
            }
            return(base.VisitMember(node));
        }
示例#5
0
        protected override Expression VisitNew(NewExpression node)
        {
            //此处一般是在Select方法中new了匿名对象,例如users.Select(x=>new {x.Id})
            foreach (System.Reflection.MemberInfo memberInfo in node.Members)
            {
                //检查当前成员的类型是否是实体类型,例如x=>new {x.User.Book.Id}
                //这种情况一般是外键访问,需要考虑与主表之间的关系

                if (ExpressionUtil.IsEntityMember(memberInfo))
                {
                    //当前成员的类型是一个实体类型,需要考虑与主表的关系
                    var type             = ExpressionUtil.GetMemberType(memberInfo);
                    var entityInfo       = _entityManager.GetEntity(type);
                    var parentExpression = FindArgument(node.Arguments, memberInfo);
                    if (parentExpression is ParameterExpression)
                    {
                        //该成员由参数直接调用,可直接考虑与主表的关系
                    }
                    string tableName = entityInfo.TableName;
                    //if (string.IsNullOrWhiteSpace(tableName))
                    //{
                    //    throw new Exception("Select子句中选择的类型没有标TableAttribute特性或者特性中指定了空表名");
                    //}

                    var pis = entityInfo.Properties;
                    //_alias.AddRange(pis.Select(x => x.Name));
                    foreach (var propertyInfo in pis)
                    {
                        _columnInfos.Add(propertyInfo.Name, new KeyValuePair <string, string>(tableName, propertyInfo.Name));
                    }
                    if (!_tableInfos.ContainsKey(tableName))
                    {
                        _tableInfos.Add(tableName, ExpressionUtil.GenerateRandomTableAlias());
                    }
                }
                else
                {
                    _columnInfos.Add(memberInfo.Name, new KeyValuePair <string, string>(_masterTableName, memberInfo.Name));
                }
            }
            return(node);
        }
        protected override Expression VisitMember(MemberExpression node)
        {
            if (node.Expression is ParameterExpression)
            {
                //到达根节点,并且一定是左枝
                if (ExpressionUtil.IsEntityMember(node.Member))
                {
                    //x.User.Book.Id
                    string tableName = ExpressionUtil.GetEntityTableName(ExpressionUtil.GetMemberType(node.Member));
                    if (string.IsNullOrWhiteSpace(tableName))
                    {
                        throw new Exception("解析出错");
                    }
                    string alia = _aliaTableNameMap[tableName];
                    field = _memberStack.Pop().Name;
                    _conditionStack.Push("[" + alia + "].[" + field + "]");
                    _conditionStack.Push("@" + field);
                }
                else
                {
                    //按照属性处理
                    field = node.Member.Name;
                    if (_memberStack.Count > 0)
                    {
                        //有属性要转换为sql语句
                        var propertyInfo = (PropertyInfo)_memberStack.Pop();
                        if (propertyInfo.PropertyType.FullName == "System.DateTime" && propertyInfo.PropertyType.Assembly.GlobalAssemblyCache)
                        {
                            //该属性为日期时间型,可进行转换
                            _conditionStack.Push("CONVERT(NVARCHAR(20),[" + field + "],101)");
                        }
                        else
                        {
                            throw new NotImplementedException("不允许使用当前属性取值:" + propertyInfo.PropertyType.Name + "," + propertyInfo.Name);
                        }
                    }
                    else if (_memberStack.Count > 0)
                    {
                        //有方法要转换为sql语句
                        var method = _memberStack.Pop();
                        if (method.Name == "ToDateTime" && method.DeclaringType.Assembly.GlobalAssemblyCache)
                        {
                            _conditionStack.Push("CONVERT(NVARCHAR(20),[" + field + "],101)");
                        }
                        else
                        {
                            throw new NotSupportedException("不支持指定方法的转换:" + method.Name);
                        }
                    }
                    else
                    {
                        _conditionStack.Push("[" + field + "]");
                    }
                    _conditionStack.Push("@" + field);
                }
            }
            else if (node.Expression == null)
            {
                //一定是静态成员,例如:x=>DateTime.Now中的Now,直接取出值
                object value = null;
                if (node.Member.MemberType == MemberTypes.Field)
                {
                    var fieldInfo = node.Member as FieldInfo;
                    value = fieldInfo.GetValue(null);
                }
                else
                {
                    var propertyInfo = node.Member as PropertyInfo;
                    value = propertyInfo.GetValue(null, null);
                }
                while (_memberStack.Count > 0)
                {
                    var member = _memberStack.Pop();
                    if (member.MemberType == MemberTypes.Field)
                    {
                        value = ((FieldInfo)member).GetValue(value);
                    }
                    else if (member.MemberType == MemberTypes.Property)
                    {
                        value = ((PropertyInfo)member).GetValue(value, null);
                    }
                    else
                    {
                        throw new NotSupportedException("未知的成员类型:" + member.MemberType);
                    }
                }
                //if (node.Member.MemberType == MemberTypes.Field)
                //{
                //    var fieldInfo = node.Member as FieldInfo;
                //    _list.Add(fieldInfo.GetValue(null));
                //}
                //else
                //{
                //    var propertyInfo = node.Member as PropertyInfo;
                //    _list.Add(propertyInfo.GetValue(null, null));
                //}
                _list.Add(_conditionStack.Peek(), value);
            }
            else if (node.Expression is ConstantExpression)
            {
                //引用的局部变量
                //var constExp = node.Expression as ConstantExpression;
                //var field = constExp.Value.GetType().GetField(node.Member.Name);
                //var rootValue = field.GetValue(constExp.Value);
                //while (_propertyStack.Count > 0)
                //{
                //    var property = _propertyStack.Pop();
                //    rootValue = property.GetValue(rootValue, null);
                //}
                //_paramStack.Push(rootValue);
                ObjectValueExpressionVisitor visitor = new ObjectValueExpressionVisitor();
                visitor.Visit(node);
                if (visitor.Value is Array || visitor.Value is IEnumerable)
                {
                    var    rootValue = visitor.Value;
                    var    list      = rootValue as IList;
                    object result    = rootValue;
                    while (_memberStack.Count > 0)
                    {
                        var memberInfo = _memberStack.Pop();
                        if (memberInfo.MemberType == MemberTypes.Method)
                        {
                            var method = memberInfo as MethodInfo;
                            IEnumerable <object> args = null;
                            //if (method.Arguments[0] is ConstantExpression)
                            //{
                            //    args = mce.Arguments.Select(x => ((ConstantExpression)x).Value);
                            //    result = mce.Method.Invoke(rootValue, args.ToArray());
                            //}
                            //else
                            //{
                            //    visitor = new ObjectValueExpressionVisitor();
                            //    visitor.Visit(mce.Arguments[0]);
                            //    var extensionArgs = mce.Arguments.Skip(1).Select(x => ((ConstantExpression)x).Value).ToList();
                            //    extensionArgs.Insert(0, visitor.Value);
                            //    result = mce.Method.Invoke(null, extensionArgs.ToArray());
                            //}
                        }
                    }
                    if (_memberStack.Count > 0)
                    {
                        //MethodCallExpression mce = _memberStack.Pop();
                        //IEnumerable<object> args = null;
                        //if (mce.Arguments[0] is ConstantExpression)
                        //{
                        //    args = mce.Arguments.Select(x => ((ConstantExpression)x).Value);
                        //    result = mce.Method.Invoke(rootValue, args.ToArray());
                        //}
                        //else
                        //{
                        //    visitor = new ObjectValueExpressionVisitor();
                        //    visitor.Visit(mce.Arguments[0]);
                        //    var extensionArgs = mce.Arguments.Skip(1).Select(x => ((ConstantExpression)x).Value).ToList();
                        //    extensionArgs.Insert(0, visitor.Value);
                        //    result = mce.Method.Invoke(null, extensionArgs.ToArray());
                        //}
                    }

                    _list.Add(_conditionStack.Peek(), result);
                    //_constStack.Push(rootValue);
                }
                else
                {
                    _constStack.Push(visitor.Value);
                }
                _paramNameStack.Push(node.Member.Name);
            }
            else if (node.Expression is MemberExpression)
            {
                if (!ExpressionReflector.IsEntityPropertyType(ExpressionUtil.GetMemberType(((MemberExpression)node.Expression).Member)))
                {
                    //x=>x.User.Book.Id
                    _memberStack.Push(node.Member);
                }
                else
                {
                    //var a=false;x=>a这种情况
                }
            }
            else
            {
                _memberStack.Push(node.Member);
            }
            return(base.VisitMember(node));
        }