当前位置: 动力学知识库 > 问答 > 编程问答 >

.net - ThenBy fails after Select

问题描述:

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.

网友答案:

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:

Performs a subsequent ordering of the elements in a sequence in ascending order.

for example in your true condition you can do (in your 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).ThenBy(J=>J.ContractId)
               Select(J => J.c);

and you can do (in your else statement):

qOrdered = q1.OrderBy(c => c.Premium).ThenBy(c=>c.ContractId);

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.

网友答案:

Change the code in your if to:

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 }).
               Select(J => J.c).
               OrderBy(J => J.p.LastName)

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

分享给朋友:
您可能感兴趣的文章:
随机阅读: