Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用字符串和嵌套反射的EntityFramework LINQ顺序_C#_Entity Framework_Reflection_Lambda_Linq To Entities - Fatal编程技术网

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
无法编译。也许,我在调试手表中测试了它,并在这里写得有点快。但是你明白了。不是真的,不-这对我来说没有意义。