LINQ动态查询库

时间:2011-02-28 10:30:57

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

我正在使用Entity Framework 4构建ASP.Net MVC 3应用程序。当执行下面的两段代码时,两个变量(query1和query2)的返回类型为

System.Data.Objects.ObjectQuery<Asset.Model.Equipment>

Query1使用ObjectContext的直接实例,但是,Query2使用存储库模式,即它在EquipmentService中调用GetEquipment,后者又在Equipment Repository中调用相同的命名方法。 Service and Repository中的两个方法都返回

IQueryable<Equipment>

如何,这是我的问题,为什么query2只有在我包含

时才会起作用
using System.Linq.Dynamic;

在我的控制器顶部

using (AssetEntities context = new AssetEntities())
        {
            var query1 = context.Equipments
            .OrderBy("it." + sidx + " " + sord)
            .Skip(pageIndex * pageSize)
            .Take(pageSize);
        }


        var query2 = equipService.GetEquipment()
            .OrderBy(sidx + " " + sord)
            .Skip(pageIndex * pageSize)
            .Take(pageSize);

如果我从控制器中省略System.Linq.Dynamic,我在Query2中收到错误

.OrderBy(sidx + " " + sord)

哪个州

The type arguments for method '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

有没有人知道为什么query1可以在不使用System.Linq.Dynamic的情况下工作,但是query2需要它来执行?

谢谢大家。

2 个答案:

答案 0 :(得分:6)

在第一个查询中,context.Equipments的类型为ObjectQuery<Equipment>ObjectQuery<T>具有.OrderBy("it." + sidx + " " + sord)所需的方法OrderBy(string)。所以第一个查询工作。

在第二个查询中,您使用equipService.GetEquipment()类型的IQueryable<Equipment>IQueryable<T>只有OrderBy的扩展方法Expression<Func<T, TKey>>作为参数,而不是string。因此,要将OrderByIQueryable<Equipment>一起使用,您必须编写类似

的内容
equipService.GetEquipment().OrderBy(e => e.equipmentID)

但它不是你可以使用的。您需要另一种扩展方法,它可以为您提供System.Linq.Dynamic格式的LINQ动态查询库。

在许多情况下,LINQ to Entities具有many restrictions,但在您的情况下,它具有LINQ to SQL的更多优势。所以我建议你留在LINQ to Entities中。我确信,通过直接在您使用的实体框架中对所有功能的本机支持,您将获得更好的性能。

因为LINQ to Entities或ObjectQuery<Equipment>支持Where(string)方法(完全是ObjectQuery.Where(string predicate, params ObjectParameter[] parameters)方法),您可以相对轻松地在jqGrid中实现过滤/搜索。 .Where的用法可以是

.Where("it.equipmentID < 100")

.Where("it.equipmentID < @maxId", new ObjectParameter ("maxId", 100))
例如

(在ObjectParameter中使用“maxId”而不是“@maxId”不输入错误。)

更新:在the answer的“更新”部分,您可以找到the example,其中显示了如何根据我在上面描述的想法在jqGrid中实现过滤/搜索。

答案 1 :(得分:4)

“it”是默认的ObjectQuery.Name属性值。实际上,当您使用第一个查询时,您执行隐式实体SQL Order By子句,而在第二个查询中您使用LINQ to Entities,它需要System.Linq.Dynamic命名空间才能正常工作。