C# 使用字符串和嵌套反射的EntityFramework LINQ顺序
我已经看到了一些类似的问题,但找不到解决这个问题的答案。C# 使用字符串和嵌套反射的EntityFramework LINQ顺序,c#,entity-framework,reflection,lambda,linq-to-entities,C#,Entity Framework,Reflection,Lambda,Linq To Entities,我已经看到了一些类似的问题,但找不到解决这个问题的答案。 我希望能够使用字符串作为属性名对集合进行排序 型号: public sealed class User : IdentityUser { #region Constructors #endregion #region Properties [Required] [Display(Name = "First name")] public string FirstName { get; s
我希望能够使用字符串作为属性名对集合进行排序 型号:
public sealed class User : IdentityUser
{
#region Constructors
#endregion
#region Properties
[Required]
[Display(Name = "First name")]
public string FirstName { get; set; }
[Required]
[Display(Name = "Last name")]
public string LastName { get; set; }
[ForeignKey("Superior")]
public string SuperiorId { get; set; }
public User Superior{ get; set; }
[NotMapped]
public string FullName => this.LastName + " " + this.FirstName;
#endregion
}
我想打一个这样的电话:
DbSet.Order("SuperiorUser.FullName", Asc/Desc)...
我下面的函数适用于顺序(“FullName”,Asc/Desc)
,但当我想更深入的时候就不行了
public static IOrderedQueryable<T> Order<T>(this IQueryable<T> source, string propertyName,
ListSortDirection direction = ListSortDirection.Ascending)
{
return ListSortDirection.Ascending == direction
? source.OrderBy(ToLambda<T>(propertyName))
: source.OrderByDescending(ToLambda<T>(propertyName));
}
private static Expression<Func<T, object>> ToLambda<T>(string propertyName)
{
var parameter = Expression.Parameter(typeof(T));
var property = Expression.Property(parameter, propertyName);
return Expression.Lambda<Func<T, object>>(property, parameter);
}
公共静态IOrderedQueryable顺序(此IQueryable源、字符串propertyName、,
ListSortDirection方向=ListSortDirection.升序)
{
返回ListSortDirection.Ascending==方向
?来源.订购人(ToLambda(propertyName))
:source.OrderByDescending(ToLambda(propertyName));
}
私有静态表达式ToLambda(字符串属性名称)
{
var参数=表达式参数(typeof(T));
var property=Expression.property(参数,propertyName);
返回表达式.Lambda(属性,参数);
}
所以我让它看起来有点像这样
private static Expression<Func<T, object>> ToLambda<T>(string propertyName)
{
var propertyNames = propertyName.Split('.');
var type = typeof(T)
ParameterExpression parameter;
MemberExpression property;
for (var propName in propertyNames)
{
parameter = Expression.Parameter(type);
property = Expression.Property(parameter, propName);
type = property.Type;
}
return Expression.Lambda<Func<T, object>>(property, parameter);
}
私有静态表达式ToLambda(字符串属性名称)
{
var propertyNames=propertyName.Split('.');
变量类型=类型(T)
参数表达式参数;
成员表达属性;
for(propertyNames中的变量propName)
{
参数=表达式。参数(类型);
property=Expression.property(参数,propName);
type=property.type;
}
返回表达式.Lambda(属性,参数);
}
但这很遗憾返回错误
,参数“”未绑定在指定的LINQ to Entities查询表达式中。我缺少什么?您需要将属性
访问方法嵌套在循环中,然后将参数应用于lambda
private static Expression<Func<T, object>> ToLambda<T>(string propertyName) {
var propertyNames = propertyName.Split('.');
var parameter = Expression.Parameter(typeof(T));
Expression body = parameter;
foreach (var propName in propertyNames)
body = Expression.Property(body, propName);
return Expression.Lambda<Func<T, object>>(body, parameter);
}
私有静态表达式ToLambda(字符串属性名称){
var propertyNames=propertyName.Split('.');
var参数=表达式参数(typeof(T));
表达式体=参数;
foreach(propertyNames中的变量propName)
body=Expression.Property(body,propName);
返回表达式.Lambda(主体,参数);
}
您需要将属性
访问方法嵌套在循环中,然后将参数应用于lambda
private static Expression<Func<T, object>> ToLambda<T>(string propertyName) {
var propertyNames = propertyName.Split('.');
var parameter = Expression.Parameter(typeof(T));
Expression body = parameter;
foreach (var propName in propertyNames)
body = Expression.Property(body, propName);
return Expression.Lambda<Func<T, object>>(body, parameter);
}
私有静态表达式ToLambda(字符串属性名称){
var propertyNames=propertyName.Split('.');
var参数=表达式参数(typeof(T));
表达式体=参数;
foreach(propertyNames中的变量propName)
body=Expression.Property(body,propName);
返回表达式.Lambda(主体,参数);
}
我曾经为iQueryTables编写了一个扩展方法,以按字符串定义的属性进行排序:
public static IOrderedQueryable<T> SortBy<T>(this IQueryable<T> source, string propertyName)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
else
{
if (propertyName.EndsWith(" ASC", StringComparison.OrdinalIgnoreCase))
propertyName = propertyName.Replace(" ASC", "");
// DataSource control passes the sort parameter with a direction
// if the direction is descending
int descIndex = propertyName.IndexOf(" DESC", StringComparison.OrdinalIgnoreCase);
if (descIndex >= 0)
{
propertyName = propertyName.Substring(0, descIndex).Trim();
}
ParameterExpression parameter = Expression.Parameter(source.ElementType, String.Empty);
MemberExpression property = Expression.Property(parameter, propertyName);
LambdaExpression lambda = Expression.Lambda(property, parameter);
string methodName = (descIndex < 0) ? "OrderBy" : "OrderByDescending";
Expression methodCallExpression = Expression.Call(typeof(Queryable), methodName,
new Type[] { source.ElementType, property.Type },
source.Expression, Expression.Quote(lambda));
return source.Provider.CreateQuery<T>(methodCallExpression) as IOrderedQueryable<T>;
}
}
public static IOrderedQueryable SortBy(此IQueryable源,字符串propertyName)
{
if(source==null)
{
抛出新的ArgumentNullException(“源”);
}
其他的
{
if(propertyName.EndsWith(“ASC”,StringComparison.OrdinalIgnoreCase))
propertyName=propertyName.Replace(“ASC”和“”);
//DataSource控件传递带有方向的sort参数
//如果方向是下降的
int descIndex=propertyName.IndexOf(“DESC”,StringComparison.OrdinalIgnoreCase);
如果(描述索引>=0)
{
propertyName=propertyName.Substring(0,descIndex.Trim();
}
ParameterExpression参数=Expression.parameter(source.ElementType,String.Empty);
MemberExpression属性=Expression.property(参数,propertyName);
LambdaExpression lambda=Expression.lambda(属性、参数);
string methodName=(descIndex<0)?“OrderBy”:“OrderByDescending”;
Expression methodCallExpression=Expression.Call(typeof(Queryable)、methodName、,
新类型[]{source.ElementType,property.Type},
source.Expression,Expression.Quote(lambda));
返回source.Provider.CreateQuery(methodCallExpression)作为IOrderedQueryable;
}
}
您可以调用LIST.AsQueryable().SortBy(“姓氏”)。我曾经为IQueryables编写了一个扩展方法,以按字符串定义的属性进行排序:
public static IOrderedQueryable<T> SortBy<T>(this IQueryable<T> source, string propertyName)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
else
{
if (propertyName.EndsWith(" ASC", StringComparison.OrdinalIgnoreCase))
propertyName = propertyName.Replace(" ASC", "");
// DataSource control passes the sort parameter with a direction
// if the direction is descending
int descIndex = propertyName.IndexOf(" DESC", StringComparison.OrdinalIgnoreCase);
if (descIndex >= 0)
{
propertyName = propertyName.Substring(0, descIndex).Trim();
}
ParameterExpression parameter = Expression.Parameter(source.ElementType, String.Empty);
MemberExpression property = Expression.Property(parameter, propertyName);
LambdaExpression lambda = Expression.Lambda(property, parameter);
string methodName = (descIndex < 0) ? "OrderBy" : "OrderByDescending";
Expression methodCallExpression = Expression.Call(typeof(Queryable), methodName,
new Type[] { source.ElementType, property.Type },
source.Expression, Expression.Quote(lambda));
return source.Provider.CreateQuery<T>(methodCallExpression) as IOrderedQueryable<T>;
}
}
public static IOrderedQueryable SortBy(此IQueryable源,字符串propertyName)
{
if(source==null)
{
抛出新的ArgumentNullException(“源”);
}
其他的
{
if(propertyName.EndsWith(“ASC”,StringComparison.OrdinalIgnoreCase))
propertyName=propertyName.Replace(“ASC”和“”);
//DataSource控件传递带有方向的sort参数
//如果方向是下降的
int descIndex=propertyName.IndexOf(“DESC”,StringComparison.OrdinalIgnoreCase);
如果(描述索引>=0)
{
propertyName=propertyName.Substring(0,descIndex.Trim();
}
ParameterExpression参数=Expression.parameter(source.ElementType,String.Empty);
MemberExpression属性=Expression.property(参数,propertyName);
LambdaExpression lambda=Expression.lambda(属性、参数);
string methodName=(descIndex<0)?“OrderBy”:“OrderByDescending”;
Expression methodCallExpression=Expression.Call(typeof(Queryable)、methodName、,
新类型[]{source.ElementType,property.Type},
source.Expression,Expression.Quote(lambda));
返回source.Provider.CreateQuery(methodCallExpression)作为IOrderedQueryable;
}
}
你可以调用LIST.AsQueryable().SortBy(“姓氏”)。你的新ToLambda
无法编译。也许,我在调试手表中测试了它,并在这里写得有点快。但是你明白了。不是真的,不-这对我来说没有意义。