给定一个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:澄清了我需要查询动态列名。
答案 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