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)); }
/// <summary> /// 是否是实体成员 /// </summary> /// <param name="memberInfo"></param> /// <returns></returns> public static bool IsEntityMember(MemberInfo memberInfo) { return(!ExpressionReflector.IsEntityPropertyType(GetMemberType(memberInfo))); }
/// <summary> /// 该类型是否可以作为实体属性的类型 /// </summary> /// <param name="type"></param> /// <returns></returns> internal static bool IsEntityPropertyType(Type type) { return(ExpressionReflector.IsEntityPropertyType(type)); }
/// <summary> /// 初始化表格的列 /// </summary> /// <param name="gridView">要初始化的DataGridView</param> /// <param name="autoSizeMode">行模式</param> /// <param name="dataSource">数据源</param> public static void InitColumns(DataGridView gridView, DataGridViewAutoSizeColumnsMode autoSizeMode = DataGridViewAutoSizeColumnsMode.Fill) { gridView.ColumnHeadersDefaultCellStyle.WrapMode = DataGridViewTriState.False; var value = gridView.DataSource; gridView.AutoSizeColumnsMode = autoSizeMode; gridView.EditMode = DataGridViewEditMode.EditProgrammatically; gridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect; gridView.AllowUserToAddRows = false; gridView.AllowUserToDeleteRows = false; if (!(value is IList)) { return; } var type = value.GetType().GetGenericArguments().FirstOrDefault(); if (type != null) { var pis = type.GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(x => ExpressionReflector.IsEntityPropertyType(x.PropertyType)); var displayType = typeof(DataGridColumnAttribute); foreach (var item in pis) { var attrs = item.GetCustomAttributes(displayType, false); if (attrs.Length <= 0) { continue; } var dn = attrs[0] as DataGridColumnAttribute; DataGridViewColumn column; if (gridView.AutoGenerateColumns) { column = gridView.Columns[item.Name]; if (column == null) { continue; } if (dn == null) { continue; } column.HeaderText = dn.DisplayName; column.Visible = dn.Visible; if (dn.Width <= 0 || dn.Width == -1) { continue; } try { column.Width = dn.Width; } catch { } } else { column = new DataGridViewTextBoxColumn(); column.HeaderText = dn.DisplayName; column.Visible = dn.Visible; column.Width = dn.Width; gridView.Columns.Add(column); } } } }