I have some stupid situation where I can't find simple and elegant solution for annoying problem.
I writing asp.net application with simple UI for querying database based on user choices. For querying DB I using Entity Framework.
In my scenario, one of the optional user choices is a free text, and for that I using SQL Server FTS capabilities (using CONTAINSTABLE function, since I need to order results by relevance).
Now, I have the following situation:
If user did not provided free text criteria, I creating simple Linq query with result of type IQueriable<Result>
(where 'Result' is an entity with data from table)
But, if user did provided free text criteria, I creating query with CONTAINSTABLE, and its type is IQueriable<ResultWithRank>
(where 'ResultWithRank' is a object contains two entities: 'Result' and 'Rank', since CONTAINSTABLE results in inner join).
At this stage, after I built my queriable, I need to execute 'Select' method on it, in order to convert it to something useful.
Here is the problem:
In first case, my select statement looks like this:
var result = queryable.Select(entity => /*.. about 20 lines of reshapying code .. */
In second case, it looks like this:
var result = queryable.Select(entity.Result => /*.. about 20 lines of exactly the same reshapying code .. */
I want to avoid duplication of "select" code, because it identical for both cases. I tried to move it to external method, but this was failing to execute, since Linq was trying to convert my method to SQL and obviously failed.
How I can resolve this problem in some elegant way, without duplicating 'select' code?
I'd use:
Expression<Func<Result, Foo>> conversion = result => { ... };
First case:
var result = queryable.Select(conversion);
Second case:
var result = queryable.Select(entity => entity.Result)
.Select(conversion);
Basically use the fact that you can perform two projections together, so that your first projection (in the second case) gets you into a situation you've already tackled.
See more on this question at Stackoverflow