/// <summary> /// 访问 IsNullOrEmpty 方法 /// </summary> /// <param name="m">方法表达式</param> protected override Expression VisitIsNullOrEmpty(MethodCallExpression m) { _builder.Append("ISNULL("); _visitor.Visit(m.Arguments[0]); _builder.Append(","); bool isUnicode = SqlServerUtils.IsUnicode(_visitedMark.Current); string empty = isUnicode ? "N''" : "''"; _builder.Append(empty); _builder.Append(") = "); _builder.Append(empty); return(m); }
/// <summary> /// 访问 string.Contains 方法 /// </summary> /// <param name="m">方法表达式</param> protected override Expression VisitStringContains(MethodCallExpression m) { // https://www.cnblogs.com/yangmingyu/p/6928209.html // 对于其他的特殊字符:'^', '-', ']' 因为它们本身在包含在 '[]' 中使用,所以需要用另外的方式来转义,于是就引入了 like 中的 escape 子句,另外值得注意的是:escape 可以转义所有的特殊字符。 // EF 的 Like 不用参数化... _visitor.Visit(m.Object); if (this.NotOperands != null && this.NotOperands.Contains(m)) { _builder.Append(" NOT"); } _builder.Append(" LIKE "); if (m.Arguments[0].CanEvaluate()) { ColumnAttribute column = null; bool isUnicode = SqlServerUtils.IsUnicode(_visitedMark.Current, out column); string value = _constor.GetSqlValue(m.Arguments[0].Evaluate().Value, _builder.TranslateContext, column); if (!_builder.Parameterized && value != null) { value = value.TrimStart('N').Trim('\''); } if (_builder.Parameterized) { _builder.Append("("); _builder.Append("'%' + "); _builder.Append(value); _builder.Append(" + '%'"); _builder.Append(")"); } else { if (isUnicode) { _builder.Append('N'); } _builder.Append("'%"); _builder.Append(value); _builder.Append("%'"); } } else { _builder.Append("('%' + "); _visitor.Visit(m.Arguments[0]); _builder.Append(" + '%')"); } return(m); }
/// <summary> /// 访问 EndWidth 方法 /// </summary> /// <param name="m">方法表达式</param> protected override Expression VisitEndsWith(MethodCallExpression m) { _visitor.Visit(m.Object); if (this.NotOperands != null && this.NotOperands.Contains(m)) { _builder.Append(" NOT"); } _builder.Append(" LIKE "); if (m.Arguments[0].CanEvaluate()) { ColumnAttribute column = null; bool isUnicode = SqlServerUtils.IsUnicode(_visitedMark.Current, out column); string value = _constor.GetSqlValue(m.Arguments[0].Evaluate().Value, _builder.TranslateContext, column); if (!_builder.Parameterized && value != null) { value = value.TrimStart('N').Trim('\''); } if (_builder.Parameterized) { _builder.Append("('%' + "); _builder.Append(value); _builder.Append(')'); } else { if (isUnicode) { _builder.Append('N'); } _builder.Append("'%"); _builder.Append(value); _builder.Append("'"); } } else { _builder.Append("('%' + "); _visitor.Visit(m.Arguments[0]); _builder.Append(')'); } return(m); }
/// <summary> /// 是否日期+时间类型 /// </summary> /// <param name="dbType">DbType属性</param> /// <returns></returns> public static bool IsDateTime(object dbType) { if (dbType == null) { return(false); } else if (dbType is DbType) { return(((DbType)dbType) == System.Data.DbType.DateTime); } else if (dbType is SqlDbType) { return(((SqlDbType)dbType) == SqlDbType.DateTime); } else { return(SqlServerUtils.ThrowException(dbType)); } }
/// <summary> /// 检查指定的数据类型是否为 Unicode /// </summary> /// <param name="dbType">数据类型 <see cref="System.Data.DbType"/> </param> /// <returns></returns> public static bool IsUnicode(object dbType) { if (dbType == null) { return(true); } else if (dbType is DbType) { return(((DbType)dbType) == System.Data.DbType.String || ((DbType)dbType) == System.Data.DbType.StringFixedLength); } else if (dbType is SqlDbType) { return(((SqlDbType)dbType) == SqlDbType.NVarChar || ((SqlDbType)dbType) == SqlDbType.NChar || ((SqlDbType)dbType) == SqlDbType.NText); } else { return(SqlServerUtils.ThrowException(dbType)); } }
/// <summary> /// 设置命令参数对象的 DbType属性 /// </summary> /// <param name="parameter">命令参数对象</param> /// <param name="dbType">DbType属性</param> public static void DbType(this SqlParameter parameter, object dbType) { if (dbType != null) { if (dbType is DbType) { parameter.DbType = (DbType)dbType; } else if (dbType is SqlDbType) { parameter.SqlDbType = (SqlDbType)dbType; } else { SqlServerUtils.ThrowException(dbType); } } else if (parameter.Value != null && parameter.Value is DateTime && dbType == null) { // 如果 DateTime 没有指定 DbType,则需要转为 DateTime2才能保持原有的精度 parameter.DbType = System.Data.DbType.DateTime2; } }
/// <summary> /// 检查字段或属性成员声明的 DbType 是否为 Unicode 数据类型 /// </summary> /// <param name="m">将要检查的字段或属性成员</param> /// <param name="column">字段或属性成员显示声明的列特性</param> /// <returns></returns> public static bool IsUnicode(MemberVisitedStack.VisitedMember m, out ColumnAttribute column) { column = m != null?TypeUtils.GetColumnAttribute(m.Member, m.ReflectedType) : null; return(SqlServerUtils.IsUnicode(column == null ? null : column.DbType)); }
/// <summary> /// 检查字段或属性成员声明的 DbType 是否为 Unicode 数据类型 /// </summary> /// <param name="m">将要检查的字段或属性成员</param> /// <returns></returns> public static bool IsUnicode(MemberVisitedStack.VisitedMember m) { ColumnAttribute column = null; return(SqlServerUtils.IsUnicode(m, out column)); }
/// <summary> /// 访问 ToString 方法 /// </summary> protected override Expression VisitToStringImpl(Expression node) { // => a.ID.ToString() // 字符串不进行转换 if (node == null || node.Type == typeof(string)) { return(_visitor.Visit(node)); } ColumnAttribute column = null; bool isUnicode = SqlServerUtils.IsUnicode(_visitedMark.Current, out column); string native = isUnicode ? "NVARCHAR" : "VARCHAR"; // 其它类型转字符串 bool isDate = node.Type == typeof(DateTime) || node.Type == typeof(DateTime?) || node.Type == typeof(TimeSpan) || node.Type == typeof(TimeSpan?) || node.Type == typeof(DateTimeOffset) || node.Type == typeof(DateTimeOffset?); if (isDate) { native = string.Format("{0}(64)", native); _builder.Append("CONVERT("); _builder.Append(native); _builder.Append(","); _visitor.Visit(node); _builder.Append(",121)"); } else if (node.Type == typeof(byte[])) { native = string.Format("{0}(max)", native); _builder.Append("CONVERT("); _builder.Append(native); _builder.Append(","); _visitor.Visit(node); _builder.Append(",1)"); } else if (node.Type == typeof(Guid)) { native = string.Format("{0}(64)", native); _builder.Append("CAST("); _visitor.Visit(node); _builder.Append(" AS "); _builder.Append(native); _builder.Append(')'); } else { if (column != null && column.Size > 0) { native = string.Format("{0}({1})", native, column.Size); } else if (column != null && column.Size == -1) { native = string.Format("{0}(max)", native); } else { native = string.Format("{0}(max)", native); } _builder.Append("CAST("); _visitor.Visit(node); _builder.Append(" AS "); _builder.Append(native); _builder.Append(')'); } return(node); }