我在动态LINQ 的VS2008示例中找到了一个示例,它允许您使用类似sql的字符串(例如,OrderBy("Name, Age DESC"))用于排序.不幸的是,包含的方法仅适用于IQueryable<T>;.有没有办法获得此功能IEnumerable<T>?
我试图从属性的名称在运行时为嵌套属性创建一个lambda表达式.基本上我正在尝试创建由以下指定的lambda表达式:
var expression = CreateExpression<Foo, object>(foo => foo.myBar.name);
private static Expression CreateExpression<TEntity, TReturn>(Expression<Func<TEntity, TReturn>> expression)
{
return (expression as Expression);
}
Run Code Online (Sandbox Code Playgroud)
随着课程:
class Foo
{
public Bar myBar { get; set; }
}
class Bar
{
public string name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
但是我得到的只是Foo字符串的类型"myBar.name"
如果它是一个普通的属性,例如只需要该值,"myBar"那么我可以使用以下内容:
private static LambdaExpression GetPropertyAccessLambda(Type type, string propertyName)
{
ParameterExpression odataItParameter = Expression.Parameter(type, "$it");
MemberExpression propertyAccess = Expression.Property(odataItParameter, propertyName);
return Expression.Lambda(propertyAccess, odataItParameter);
}
Run Code Online (Sandbox Code Playgroud)
但是,此代码不适用于嵌套属性,我不知道如何创建LambdaExpression来完成工作foo.myBar.name.
我认为这将是这样的:
GetExpression(Expression.Call(GetExpression(Foo, "myBar"), "name")) …Run Code Online (Sandbox Code Playgroud) 可能重复:
动态LINQ OrderBy
switch (sort) {
case "Title":
queryResults = queryResults.OrderBy(r => r.Title);
break;
default:
queryResults = queryResults.OrderBy(r => r.LastName);
break;
Run Code Online (Sandbox Code Playgroud)
有什么办法可以摆脱上面的开关块吗?
我可以做一些事情:
queryResults = queryResults.OrderBy(r => r."sort");
or
queryResults = queryResults.OrderBy(r => r.sort);
Run Code Online (Sandbox Code Playgroud) 我的最终目标是遍历lambda表达式中的嵌套属性,并确定是否有任何属性为null,但是我在创建基于成员表达式的新lambda表达式时遇到了问题.
采取这种虚拟方法:
public static void DoStuff<TModelDetail, TValue>(Expression<Func<TModelDetail, TValue>> expr, TModelDetail detail)
{
var memberExpression = expr.Body as MemberExpression;
if (memberExpression == null && expr.Body is UnaryExpression)
{
memberExpression = ((UnaryExpression)expr.Body).Operand as MemberExpression;
}
var pe = Expression.Parameter(typeof(TModelDetail), "x");
var convert = Expression.Convert(memberExpression, typeof(object));
var wee = Expression.Lambda<Func<TModelDetail, object>>(convert, pe);
var hey = wee.Compile()(detail);
}
Run Code Online (Sandbox Code Playgroud)
在Compile.exec行上,我收到以下错误:
从范围''引用的'Blah'类型的变量'x',但它没有定义
其中Blah是TModelDetail的类型.
如何使用MemberExpression构建lambda?我最终想要做的是递归地找到根成员表达式,确定它是否为null,并冒泡并确定每个后续成员表达式是否为空.
我希望我的Web API能够通过字符串参数对其输出进行排序,例如:
http://myapi.com/api/people?skip=0&take=50&orderBy=lastName&descending=true.
因为我也有分页支持(skip和take我的API),我想orderBy和descending参数直接应用于SQL查询,使正确的结果来自于数据库.
但是,在执行此操作时,在尝试将参数orderBy与我希望通过字符串比较排序的类的实际属性进行匹配时,代码可能变得非常难以管理.
我找到了一个解决方案,该解决方案应该与LINQ to Entities一起工作,因此也适用于新的EF7,但是当我尝试使用新的Core CLR编译此代码时,我收到以下消息:
错误CS1503参数2:无法从'System.Linq.Expressions.Expression>'转换为'string'
失败的解决方案的代码是OrderBy<T>方法:
public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string propertyName)
{
return source.OrderBy(ToLambda<T>(propertyName));
}
Run Code Online (Sandbox Code Playgroud)
似乎新的Core CLR不支持这种尝试.有没有其他方法可以使解决方案与新的CLR一起使用?如果不是,我还有什么其他选择来使用EF7进行排序而不会导致无数if或switch语句将输入字符串与属性名称进行比较?
我有一个类对象列表ListUser。我需要能够传入一个字符串值,并使用文本表达式按该列按升序或降序排列。我所看到的所有使用 Lambda 表达式的东西都将对象属性作为强类型值,如何通过添加“名字降序”作为参数来实现这一点?
代码如下
namespace SortLists
{
class ListUser
{
public int id { get; set; }
public string firstname { get; set; }
public string lastname { get; set; }
public string company { get; set; }
public string phonenumber { get; set; }
}
class Program
{
static void Main(string[] args)
{
var user1 = new ListUser() { id = 1, firstname = "James", lastname = "Smith", company = "Code Logic", phonenumber = "01235 566 456" …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用动态参数进行制作和排序,这是代码:
var res = from c in db.CUSTOMERS select c;
if (!string.IsNullOrEmpty(sortBy) && !string.IsNullOrEmpty(direction))
{
var property = typeof(CUSTOMERS).GetProperty(sortBy);
if(direction == "asc")
{
res = res.OrderBy(x => property.GetValue(x));
}
else
{
res = res.OrderBy(x => property.GetValue(x));
}
}
return res.ToList();
Run Code Online (Sandbox Code Playgroud)
但我收到此错误:
LINQ to Entities 无法识别“System.Object GetValue(System.Object)”方法,并且该方法无法转换为存储表达式。