【问题标题】:Linq To Entities - OrderByLinq 到实体 - OrderBy
【发布时间】:2011-02-25 09:17:34
【问题描述】:

我正在关注 Phil Haacks 关于将 JQGrid 与 ASP.Net MVC 结合使用的教程。我的应用程序是使用 Entity Framework 4 的 ASP.Net MVC 3。

我有以下代码对返回到 JQGrid 的数据执行排序和分页

var query = equipService.GetAllEquipment().AsQueryable()
                .OrderBy("it." + sidx + " " + sord)
                .Skip(pageIndex * pageSize)
                .Take(pageSize);

但是,此代码会在 .OrderBy("it." + sidx + " " + sord) 行产生错误。错误是

System.Linq.Queryable.OrderBy<TSource,TKey>(System.Linq.IQueryable<TSource>, System.Linq.Expressions.Expression<System.Func<TSource,TKey>>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

查询正在调用我的服务层中的方法 GetAllEquipment(),如下所示

public List<Equipment> GetAllEquipment()
    {
        List<Equipment> equipList = new List<Equipment>();
        equipList = equipRepository.GetAllEquipment();

        return equipList;
    }

这个方法,然后在我的仓库中调用同名的方法,像这样

public List<Equipment> GetAllEquipment()
    {
        var query = (from e in Data.DBEntities.Equipments
                     select e).ToList();

        return query;
    }

我可以通过在我的控制器方法中创建我的 objectcontext 的实例并使用此代码来解决问题

using (AssetEntities context = new AssetEntities())
        {
            int pageIndex = Convert.ToInt32(page) - 1;
            int pageSize = rows;
            int totalRecords = context.Equipments.Count();
            int totalPages = (int)Math.Ceiling((float)totalRecords / (float)pageSize);


            var query = context.Equipments
              .OrderBy("it." + sidx + " " + sord)
              .Skip(pageIndex * pageSize)
              .Take(pageSize);

        }

但是,我并不想这样做,而是希望保留我在整个应用程序中用于所有数据库交互的存储库模式。

关于如何解决此问题的任何想法?

一如既往地感谢大家。

【问题讨论】:

  • .OrderBy("it." + sidx + " " + sord)not 动态 LINQ 语法。它是 ESQL / QueryBuilder 语法。你知道你调用的是哪个方法吗?
  • @Craig:我必须下载动态查询库,如 weblogs.asp.net/scottgu/archive/2008/01/07/... 所述,然后在顶部引用 System.Linq.Dynamic我的控制器。我的代码现在可以工作了 :) 谢谢。

标签: entity-framework-4 asp.net-mvc-3 jqgrid linq-to-entities entity


【解决方案1】:

我建议您使用 PropertyInfoGetPropertyFieldInfoGetField,具体取决于您的数据模型。在这种情况下,您可以在没有任何扩展的情况下实现OrderBy 操作。详情请见the answer

已更新:我再次仔细阅读了您的问题。在我看来,您的问题在 GetAllEquipment 方法中。它返回 List&lt;Equipment&gt; 而不是 IQueryable&lt;Equipment&gt;。所以GetAllEquipment 方法获取“SELECT * FROM it.Equipment”并将数据作为List 返回,它们不再是实体。使用equipService.GetAllEquipment().AsQueryable(),您将拥有IQueryable&lt;Equipment&gt; 对象,但您将不再使用LINQ to Entity,因此您应该不使用“它”。名称前的前缀。

【讨论】:

  • @Oleg。我更新了我的存储库和服务类以返回 IQueryable。我也拿出了“它”。超出我的 OrderBy 条款。我的查询现在看起来像这样但同样的错误仍然存​​在。
  • 不,我的代码仍然无法运行 Oleg。我仍然收到错误 .OrderBy(sidx + " " + sord)
  • @Oleg: 如果我将我的查询更改为这个...var query =equipService.GetEquipment() .OrderBy(e => e.equipmentID) .Skip(pageIndex * pageSize) .Take(pageSize );这行得通。所以看起来我的问题是我正在使用的动态 OrderBy 子句......
  • @tgriffiths:您是否尝试过使用GetProperty 来实现数据排序,就像我在stackoverflow.com/questions/4078592/… 中所做的那样?
  • @Oleg:我终于解决了。我必须按照weblogs.asp.net/scottgu/archive/2008/01/07/… 的说明下载动态查询库,然后在我的控制器顶部引用 System.Linq.Dynamic。我的代码现在可以工作了 :) 感谢您的帮助。
【解决方案2】:

您的存储库非常错误。它总是将所有数据从数据库加载到应用程序,并在 Web 服务器的内存中执行分页和排序。这与您的上一个查询有很大的不同,后者在 db 中执行排序和分页,并且只返回一页的数据。如果要在控制器中创建查询,存储库和服务都必须返回 IQueryable,并且它们不能调用 ToList。调用 ToList 执行当前查询。

【讨论】:

  • 我将服务和存储库方法都更改为返回 IQueryable,然后将控制器中的调用更改为 IQueryable query =equipService.GetEquipment() .OrderBy(sidx + " " + sord) .Skip(pageIndex * pageSize) .Take(pageSize);
  • 但是,我仍然遇到与上述相同的错误。有什么想法吗?
  • 您是否在使用一些特殊的 Linq 扩展,例如 Dynamic Linq?因为常见的 OrderBy 不允许将排序指定为字符串。
  • 是的,我使用的是Dynamic Linq,从下一行可以看出。OrderBy("it." + sidx + " " + sord) 我正在将字符串连接在一起。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-02
  • 2017-04-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多