Select 之后 thenBy 失败
我试图按另一个表中的某个值(通过 Join)对我的主表(Contract)进行排序,然后再次将其减少为 Contracts 并按 Contract 中的值对其进行排序(ThenBy)。
这是我的问题的简短版本:
是否可以将复合匿名类型(由 Join 生成)减少为已定义类型,而不将 IOrderedQueryable 转换为 IQueryable?
带示例的问题的长版本:
我的生产代码非常复杂,但为了这个问题的目的,我将其分解为一个简单的示例:
static void simple()
{
bool condition = true;
var ctx = new LxDataContext();
IQueryable<Contract> q1 = ctx.Contracts.Join(ctx.ContractDetails, c => c.ContractId, cd => cd.ContractId, (c, cd) => new { c, cd }).
Where(J => J.cd.DetailNo > 0).
Select(J => J.c);
IOrderedQueryable<Contract> qOrdered;
if (condition)
{
qOrdered = (IOrderedQueryable<Contract>)q1.Join(ctx.ContractPartners, c => c.ContractId, cp => cp.ContractId, (c, cp) => new { c, cp }).
Join(ctx.VwPartners, J => J.cp.PartnerId, p => p.PartnerId, (J, p) => new { J.c, p }).
OrderBy(J => J.p.LastName).
Select(J => J.c);
}
else
qOrdered = q1.OrderBy(c => c.Premium);
IOrderedQueryable<Contract> qReady = (qOrdered).ThenBy(c => c.ContractId); //if condition == true exception here
var dump = qReady.Skip(50).Take(50).ToList();
}
当条件为 false 时,一切都会正常工作。 然而,当执行更复杂的 OrderBy() 时,ThenBy() 会失败并出现以下异常:
Expression of type 'System.Linq.IQueryable`1[InfoServiceTests.DB.Contract]' cannot be used for parameter of type 'System.Linq.IOrderedQueryable`1[InfoServiceTests.DB.Contract]' of method 'System.Linq.IOrderedQueryable`1[InfoServiceTests.DB.Contract] ThenBy[Contract,Int32](System.Linq.IOrderedQueryable`1[InfoServiceTests.DB.Contract], System.Linq.Expressions.Expression`1[System.Func`2[InfoServiceTests.DB.Contract,System.Int32]])'
因此,即使我将其转换为 IOrderedQueryable<> qOrdered 似乎不是 IOrderedQueryable<>然后 ThenBy() 失败。是否可以按另一个表中的某些内容进行排序,然后将结果减少为 Contract,然后再次排序?
一些评论:
- 如果对您有任何帮助:在我的生产代码中,我有一个通用排序类,主要取自 这个答案。
- 是的,我知道这个示例可以很容易地修复,但在我的生产代码中,我需要一个通用的解决方案来按用户定义的值进行排序。这涉及到循环并将 Queryable 传递给函数。
I'm trying to Order my main table(Contract) by some value in another table (via Join) then reduce it to Contracts again and sort it (ThenBy) by a value in Contract.
Here's the short version of my question:
Is it possible to reduce a composite Anonymous type (produced by a Join) to a defined type without turning my IOrderedQueryable into an IQueryable?
Long version of the question with example:
My production code is quite complex but for the purpose of this question I've broken it down to a simple example:
static void simple()
{
bool condition = true;
var ctx = new LxDataContext();
IQueryable<Contract> q1 = ctx.Contracts.Join(ctx.ContractDetails, c => c.ContractId, cd => cd.ContractId, (c, cd) => new { c, cd }).
Where(J => J.cd.DetailNo > 0).
Select(J => J.c);
IOrderedQueryable<Contract> qOrdered;
if (condition)
{
qOrdered = (IOrderedQueryable<Contract>)q1.Join(ctx.ContractPartners, c => c.ContractId, cp => cp.ContractId, (c, cp) => new { c, cp }).
Join(ctx.VwPartners, J => J.cp.PartnerId, p => p.PartnerId, (J, p) => new { J.c, p }).
OrderBy(J => J.p.LastName).
Select(J => J.c);
}
else
qOrdered = q1.OrderBy(c => c.Premium);
IOrderedQueryable<Contract> qReady = (qOrdered).ThenBy(c => c.ContractId); //if condition == true exception here
var dump = qReady.Skip(50).Take(50).ToList();
}
When condition is false everything works as excepted.
However when the more complex OrderBy() is executed the ThenBy() fails with this exception:
Expression of type 'System.Linq.IQueryable`1[InfoServiceTests.DB.Contract]' cannot be used for parameter of type 'System.Linq.IOrderedQueryable`1[InfoServiceTests.DB.Contract]' of method 'System.Linq.IOrderedQueryable`1[InfoServiceTests.DB.Contract] ThenBy[Contract,Int32](System.Linq.IOrderedQueryable`1[InfoServiceTests.DB.Contract], System.Linq.Expressions.Expression`1[System.Func`2[InfoServiceTests.DB.Contract,System.Int32]])'
So even though I cast it to IOrderedQueryable<> qOrdered doesn't seem to be IOrderedQueryable<> and ThenBy() fails. Is it possible to sort by something in another table then reduce the result to Contract and ThenBy-sort it again?
Some comments:
- If it's any help to you: In my production code i have a generic sorting class mostly taken from this answer.
- Yes I know the example could easily be fixed, but in my Production code I need a generic solution for sorting by user-defined values. This invloves looping and passing the Queryables around to functions.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当条件确定时,您应该添加一些排序,因为在选择查询后,您的查询不是有序查询,并且 ThenBy 仅在有序查询后起作用:
例如,在您的真实条件下,您可以执行以下操作(在您的 if 条件中):
并且您可以执行以下操作(在您的 else 语句中):
另外,您应该在 if 语句之后删除当前的 ThenBy 操作。
事实上你应该找到一些可排序的东西并按它排序,然后使用ThenBy。
When Condition is OK you should add some ordering becausae after select your query is not ordered query and ThenBy just works after ordered query:
for example in your true condition you can do (in your if condition):
and you can do (in your else statement):
Also you should remove your current ThenBy operation after your if statements.
In fact you should find something which is orderable and OrderBy it, then use ThenBy.
将 if 中的代码更改为:
这将返回 IOrderedQueryable。如果 Select 添加到末尾,您将得到一个普通的 IQueryable,它不能用 ThenBy 进行排序
Change the code in your if to:
This will return an IOrderedQueryable. If the Select is add the end, you will get a normal IQueryable which can't be ordered with a ThenBy