Reputation: 29664
I have LINQ statement that looks like this:
return ( from c in customers select new ClientEntity() { Name = c.Name, ... });
I'd like to be able to abstract out the select into its own method so that I can have different "mapping" option. What does my method need to return?
In essence, I'd like my LINQ query to look like this:
return ( from c in customers select new Mapper(c));
Edit:
This is for LINQ to SQL.
Upvotes: 2
Views: 4138
Reputation: 243041
BTW: The solutions described here will work only if you want to use the 'factored' part of the code in a separate query clause (e.g. Select). If you'd like to use it as part of a clause that also does some other thing (perhaps return anonymous type with some other information), you'll need to construct the whole expression tree dynamically using Expression.Xyz methods.
Alternatively you could use the trick for embedding lambda expressions that I described here:
Upvotes: 0
Reputation: 155915
You might have to use chained methods instead of using LINQ syntax, and then you'll be able to pass in any of a variety of Expression
<
Func<TSource, TResult>
>
values that you specify:
Expression<Func<CustomerTable, Customer>> someMappingExpression = c => new Customer { Name = c.Name };
return context.CustomerTable.Select(someMappingExpression);
UPDATE: Select
takes a Func
, not an Expression
UPDATE: The Select
function that should be used does take an Expression<Func>
, rather than just a Func
.
Upvotes: 1
Reputation: 116654
New answer now I've noticed that it's Linq to SQL... :)
If you look at the version of Select that works on IQueryable<T>
it doesn't take a Func<In, Out>
. Instead, it takes an Expression<Func<In, Out>>
. The compiler knows how to generate such a thing from a lambda, which is why your normal code compiles.
So to have a variety of select mapping functions ready to use by passing them to Select, you could declared them like this:
private static readonly Expression<Func<CustomerInfo, string>> GetName = c => c.Name;
private static readonly Expression<Func<CustomerInfo, ClientEntity>> GetEntity = c => new ClientEntity { Name = c.Name, ... };
You would then use them like this:
var names = customers.Select(GetName);
var entities = customers.Select(GetEntity);
Upvotes: 4
Reputation: 8357
This is for linq to objects? Or for a linq to ?
Because ... select new Mapper(c), requires that 'c' is already materialized into an object, and then passed to the Mapper() CTor. (as 'c' is not known at the db level, only at the .NET level)
Upvotes: 0