【问题标题】:Better way to Sort a Queryable by any property按任何属性对 Queryable 进行排序的更好方法
【发布时间】:2015-07-13 23:49:41
【问题描述】:

这种情况类似于Better way to Sort a List by any property,但在这种情况下,在执行方法'.ToList()'之前内存中没有列表。

我想在执行数据库查询之前进行排序。我想在他执行之前“编写” SQL 查询。

我的代码:

public virtual DataTablesData<TViewModel> DataTablesGetData(DataTablesParam model)
{
    var paged = new DataTablesData<TViewModel>();
    IQueryable<TEntity> qr;

    try
    {
        using (var db = new EdmxMSSQLContainer())
        {
            List<TViewModel> list = null;

            qr = db.Set<TEntity>();

            int iColumn = model.Order.FirstOrDefault().Column;
            var property = typeof(TEntity).GetProperty(model.Columns.ToArray()[iColumn].Data);
            var param = Expression.Parameter(typeof(TEntity));
            Expression final = Expression.Property(param, property);

            if (property.PropertyType.IsValueType)
            {
                final = Expression.MakeUnary(ExpressionType.Convert, final, typeof(object));
            }

            var lambda = Expression.Lambda<Func<TEntity, object>>(final, param);

            if (model.Order.FirstOrDefault().Dir.Equals("asc"))
            {
                qr = qr.OrderBy(lambda);
            }
            else
            {
                qr = qr.OrderByDescending(lambda);
            }

            // THIS LINE THROW EXCEPTION
            // qr.ToList() execute SQL Query
            list = Mapper.Map(qr.ToList(), list);

            paged.recordsTotal = this.CountRecords();
            paged.recordsFiltered = list.Count();
            paged.data = list;
        }
    }
    catch (Exception ex)
    {
        OnError(ex);
    }

    return paged;
}

这行抛出异常:

list = Mapper.Map(qr.ToList(), list);

例外:

无法将类型 System.Int32 转换为类型 System.Object。 LINQ to Entities 仅支持转换 EDM 基元或枚举类型

【问题讨论】:

    标签: c# entity-framework generics reflection func


    【解决方案1】:

    我找到了一个更好的方法来做到这一点。我必须执行以下步骤:

    1 - 在项目中添加包“Linq Dynamic”:

    Install-Package System.Linq.Dynamic.Library
    

    2 - 在 Class 中导入包:

    using System.Linq.Dynamic;
    

    3 - 可通过属性的字符串名称查询的顺序:

    qr.OrderBy(stringPropertyName);                 //asc
    qr.OrderBy(stringPropertyName + " descending"); //des
    

    它非常适合我。

    【讨论】:

    • 我认为我的 OrderByString 包更全面(支持 IEnumerable 和 IQueryable)并且更灵活(接受诸如“property1 asc, property2 desc”之类的字符串。NuGet:nuget.org/packages/OrderByString 和来源:@987654322 @
    • 你的包接受任何类型的属性,除了字符串类型?
    • 是的。标题中的“字符串”一词是指您可以将字符串传递给它,它会将其解释为一个或多个属性名称。因为它实际上将OrderBy("property1 asc, property2 desc") 之类的东西变成了OrderBy(v=&gt;v.property1).ThenByDescending(v=&gt;v.property2),所以它可以很好地与其他技术配合使用。
    【解决方案2】:

    你可以试试这个:

        Func<IQueryable<Entity>, IOrderedQueryable<Entity>> orderBy = query => query.OrderBy(e => e.ID);
    
                    Expression<Func<Entity, bool>> fitler = e => e.Active;  
    
    
    public virtual IEnumerable<T> Get(Expression<Func<T, bool>> filter = null, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null)
                {
                    IQueryable<T> query = dbSet;
    
                    if (filter != null)
                        query = query.Where(filter);
    
                    if (orderBy != null)
                        return orderBy(query).ToList();
                    else
                        return query.ToList();
                }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-16
      • 2011-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-21
      • 1970-01-01
      相关资源
      最近更新 更多