将ObjectSet限制为相关实体,并按动态列名称排序

时间:2012-08-09 21:54:56

标签: sql-server linq entity-framework linq-to-entities linq-expressions

给定一个Parent和一个有效的columnName,我想找到所有相关的Children,按动态列名排序。以下是我认为代码的外观:

Parent.                                             // EntityObject
Children.                                           // EntityCollection
Where(c => c.Gender == 'm').                        // IEnumerable
OrderBy(columnName, ListSortDirection.Ascending).   // -- not available --
Skip(pages * pageSize).Take(pageSize);

IEnumerable.OrderBy(string columnName)不存在。为了完成“按动态列名排序”,我开始使用这个外观漂亮的解决方案:How do I create an expression tree for run time sorting?,但这可以在IQueryable上运行

如果确实如此,我认为它会将记录通过网络分类并降低我的寻呼机的性能。所以我重新排序:

Repository.                                         // Repository
Children.                                           // ObjectSet
Where(c => c.Parent == Parent && c.Gender == 'm').  // ObjectQuery, runtime error
OrderBy(columnName, ListSortDirection.Ascending).   // IOrderedQueryable
Skip(pages * pageSize).Take(pageSize);

ObjectSet和ObjectQuery实现OrderBy(string columnName),此代码编译,但产生错误:

  

无法创建“DataModel.Parent”类型的常量值。只要   支持原始类型(例如Int32,String和Guid')   这个背景。

当然,我可以获取父ID,但Child.ParentReference也是非基本类型。

我可以想到一些导致整个记录集加载的方法,但我觉得我必须遗漏一些东西,因为一定要把一套基本的指令传递到数据库是不是很难使用所有以MS为中心的技术。

编辑:假装我http://en.wikipedia.org/wiki/Quiverfull,并需要对我的孩子进行分页。 :) edit2:澄清了我需要查询动态列名。

3 个答案:

答案 0 :(得分:1)

var parents = db.Parents; // Do whatever you need to get your unsorted collection from EF here.

if (sortBy == "Gender")
{
    parents = parents.OrderBy(p => p.Gender);
}
else if (sortBy == "FirstName")
{
    parents = parents.OrderBy(p => p.FirstName);
}

现在,这显然不是对多列进行排序,而只是单个列。并且您还可以为排序方向添加更多逻辑。

编辑:拿出关于PredicateBuilder的垃圾,当我开始输入这个答案时,我走错了路,忘记取出旧的东西。

答案 1 :(得分:0)

尝试更换OrderBy

OrderBy("age", ListSortDirection.Ascending).

OrderBy(x => x.Age).

也是Where

Where(c => c.Parent == Parent && c.Gender = 'm').

应该阅读

Where(c => c.Parent == Parent && c.Gender == 'm').

答案 2 :(得分:0)

所以我遇到了几个问题,这两个问题都在问题标题中提到过。

按运行时选择的或动态的列名排序需要一些表达式构建。我使用了@ Slace的流行扩展方法here

这需要一个IQueryable。 IQueryable对我有用,因为每当我不小心将我的查询转换为可枚举的时候,我当然会在分页之前将所有结果带回线,这是我试图避免的。但我仍然需要一种方法来获得与我已经拥有的实体有关系的结果的IQueryable。

我忽略了something simple,只是加入了Entity.Id工作,并没有导致数据源的冗余连接。不像我预期的那样面向对象,但它会这样做。

Repository.                                         // Repository
Children.                                           // ObjectSet
Where(c => c.Parent.Id == Parent.Id).               // ObjectQuery, works fine
OrderBy(columnName, ListSortDirection.Ascending).   // IOrderedQueryable
Skip(pages * pageSize).Take(pageSize);              // Only transfers 1 page