SqlFunc.Subqueryable.Where(Expression) 报错 返回
private void button5_Click(object sender, EventArgs e) { //程序启动时配置 SqlSugar.SqlSugarClient client = new SqlSugarClient(new ConnectionConfig { DbType = DbType.SqlServer, ConnectionString = "......链接字符串", IsAutoCloseConnection = true, }); using (client) { string sql = "True"; var expression1 = BuildExpression<View_ReportQuery>(sql); // 通过反射访问 Parameters 集合 // 这段代码没有问题 var list1 = client.Queryable<View_ReportQuery>().Where(expression1).ToPageList(0,10); // 这段代码报错 <<<<< /* *System.ArgumentOutOfRangeException: Index and length must refer to a location within the string. (Parameter 'length') at System.String.Substring(Int32 startIndex, Int32 length) at SqlSugar.ExpressionContext.GetTranslationColumnName(String columnName) at SqlSugar.SubAnd.GetValue(Expression expression) at SqlSugar.SubResolve.<>c__DisplayClass10_0.<GetSubItems>b__6(ISubOperation it) at System.Linq.Enumerable.SelectListIterator`2.ToList() at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source) at SqlSugar.SubResolve.GetSubItems() at SqlSugar.SubResolve.GetSql() at SqlSugar.MethodCallExpressionResolve..ctor(ExpressionParameter parameter) at SqlSugar.BaseResolve.Start() at SqlSugar.LambdaExpressionResolve..ctor(ExpressionParameter parameter) at SqlSugar.BaseResolve.Start() at SqlSugar.ExpressionContext.Resolve(Expression expression, ResolveExpressType resolveType) at SqlSugar.QueryBuilder.GetExpressionValue(Expression expression, ResolveExpressType resolveType) at SqlSugar.QueryableProvider`1._Where(Expression expression) at SqlSugar.QueryableProvider`1.Where(Expression`1 expression) * */ var list2 = client.Queryable<View_ReportList>().Where(t=> SqlFunc.Subqueryable<View_ReportQuery>().Where(expression1).Where(s=>s.StudyKey == t.StudyKey).Any()) .ToPageList(0, 10); Expressionable<View_ReportQuery> expressionable = new Expressionable<View_ReportQuery>(); expressionable.And(t => true); var expression2 = expressionable.ToExpression(); // 这段代码正常 var list3 = client.Queryable<View_ReportList>().Where(t => SqlFunc.Subqueryable<View_ReportQuery>() .Where(expression2) .Where(s => s.StudyKey == t.StudyKey) .Any()).ToPageList(0, 10); } } public static Expression<Func<T, bool>> BuildExpression<T>(string queryDynamicExpression) where T : class, new() { if (!string.IsNullOrWhiteSpace(queryDynamicExpression)) { var queryExpression = (Expression<Func<T, bool>>) DynamicExpressionParser.ParseLambda(typeof(T), typeof(bool), queryDynamicExpression); return queryExpression; } return null; }
我发现,用dynamiclinq的
DynamicExpressionParser
将一个表达式转换为Expression之后,在queryable.Where 中执行正常,在
SqlFunc.Subqueryable<View_ReportQuery>().Where(expression1)
执行就报异常。
但是用
Expressionable
构建的相同的Expression
SqlFunc.Subqueryable<View_ReportQuery>().Where(expression2)
执行又是正常,请问这个问题怎么解决啊?
我注意到
expression1.Parameters[0].Name 是空字符串
expression2.Parameters[0].Name 是字符串t
有没有可能是这里导致的问题?
如何让expression1.Parameters[0].Name有值?
热忱回答(12)
-
fate sta VIP02024/5/15
https://www.donet5.com/Home/Doc?typeId=2314 尽量用自带的表格查询
0 回复 -
fate sta VIP02024/5/15
或者提供完整DEMO
0 回复 -
n27741 VIP02024/5/15
@fate sta:
建表脚本
CREATE TABLE Student
(
id int,
Name varchar(20)
)
go
insert into Student (id,Name) values (1,'s1')
insert into Student (id,Name) values(2,'s2')
go
点击3号按钮即可看到错误。谢谢回复。
0 回复 -
n27741 VIP02024/5/15
我发现了,应该是 ParameterExpressionName 导致的问题。
dynamic linq 可以设置RenameEmptyParameterExpressionNames = true,指定一个随机的ParameterExpressionName。既可以执行SqlFunc.Subqueryable<View_ReportQuery>().Where(exp)
public static Expression<Func<T, bool>> BuildExpression<T>(string queryDynamicExpression) where T : class, new() { if (!string.IsNullOrWhiteSpace(queryDynamicExpression)) { ParsingConfig ps = new ParsingConfig() { RenameEmptyParameterExpressionNames = true, }; var queryExpression = (Expression<Func<T, bool>>) DynamicExpressionParser.ParseLambda<T, bool>(ps, true, queryDynamicExpression); return queryExpression; } return null; }
@n27741:
0 回复 -
fate sta VIP02024/5/15
//启动时配置 SqlSugar.StaticConfig.DynamicExpressionParserType = typeof(DynamicExpressionParser); //直接用 var exp= DynamicCoreHelper.GetWhere<Student>("it", $"it.Id=={1}");
0 回复 -
fate sta VIP02024/5/15
用现成的就行了ORM有封装
0 回复 -
n27741 VIP02024/5/15
@fate sta:
请教,GetWhere 方法要求,一个shortName 和 FormattableString WhereSql
但是我的需求是,写 Name == "Test" 或者 1==1 这样的表达式。那么WhereSql 是不是不好用了?
0 回复 -
fate sta VIP02024/5/15
@n27741:都可以用
0 回复 -
fate sta VIP02024/5/15
FormattableString 这个类型只要会玩了就全会了。
0 回复 -
n27741 VIP02024/5/15
@fate sta:
您说的是这个意思吗?如果写1==1,或者 Name=="test"
var formattableString = FormattableStringFactory.Create(queryDynamicExpression, new object[] { }); var exp = DynamicCoreHelper.GetWhere<T>("t", formattableString); return exp;
0 回复 -
fate sta VIP02024/5/15
是的
0 回复 -
n27741 VIP02024/5/15
@fate sta:收到,谢谢。
0 回复