Dav*_*eer 11 c# linq linq-to-entities asp.net-mvc-3
以下Linq-to-Entities查询工作正常:
var query = repository.Where(r => r.YearProp1.HasValue &&
r.YearProp1 >= minYear &&
r.YearProp1 <= maxYear);
Run Code Online (Sandbox Code Playgroud)
我的数据库有十几个列,它们都报告与年份相关的信息(short?数据类型).我想为所有这些列重用相同的Linq-to-Entities逻辑.就像是:
Func<RepoEntity, short?> fx = GetYearPropertyFunction();
var query = repository.Where(r => fx(r).HasValue &&
fx(r) >= minYear &&
fx(r) <= maxYear);
Run Code Online (Sandbox Code Playgroud)
这会导致错误:
LINQ to Entities无法识别方法'System.Nullable`1 [System.Int16] fx(RepoEntity)'方法,并且此方法无法转换为商店表达式.
我理解为什么我收到错误,但我想知道是否有一个解决方法,不涉及重复代码十几次只是为了更改SQL查询运行的属性.
我会在多个查询中重用该函数,所以我想我的问题的一般版本是:有没有办法将简单的property-getter lambda函数转换为Linq-to-Entities可以使用的Expression?
以 Rapha\xc3\xabl Althaus\' 答案为基础,但添加您最初寻找的通用选择器:
\n\npublic static class Examples\n{\n public static Expression<Func<MyEntity, short?>> SelectPropertyOne()\n {\n return x => x.PropertyOne;\n }\n\n public static Expression<Func<MyEntity, short?>> SelectPropertyTwo()\n {\n return x => x.PropertyTwo;\n }\n\n public static Expression<Func<TEntity, bool>> BetweenNullable<TEntity, TNull>(Expression<Func<TEntity, Nullable<TNull>>> selector, Nullable<TNull> minRange, Nullable<TNull> maxRange) where TNull : struct\n {\n var param = Expression.Parameter(typeof(TEntity), "entity");\n var member = Expression.Invoke(selector, param);\n\n Expression hasValue = Expression.Property(member, "HasValue");\n Expression greaterThanMinRange = Expression.GreaterThanOrEqual(member,\n Expression.Convert(Expression.Constant(minRange), typeof(Nullable<TNull>)));\n Expression lessThanMaxRange = Expression.LessThanOrEqual(member,\n Expression.Convert(Expression.Constant(maxRange), typeof(Nullable<TNull>)));\n\n Expression body = Expression.AndAlso(hasValue,\n Expression.AndAlso(greaterThanMinRange, lessThanMaxRange));\n\n return Expression.Lambda<Func<TEntity, bool>>(body, param);\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n可以像您正在寻找的原始查询一样使用:
\n\nExpression<Func<MyEntity, short?>> whatToSelect = Examples.SelectPropertyOne;\n\nvar query = Context\n .MyEntities\n .Where(Examples.BetweenNullable<MyEntity, short>(whatToSelect, 0, 30));\nRun Code Online (Sandbox Code Playgroud)\n