LINQ to SQL Projection: Func vs Inline
I am finding some unexpected behavior when using a projection in a LINQ to SQL query using a Func. Example code will explain better than words.
A basic L2S lambda query using projection:
db.Entities.Select(e => new DTO(e.Value));
It translates to the desired SQL:
SELECT [t1].[Value]
FROM [Entity] AS [t1]
However, when the projection is put into a Func like this:
Func<Entity, DTO> ToDTO = (e) => new DTO(e.Value);
And called like this:
db.Entities.Select(e => ToDTO(e));
The SQL is now pulling back all of the columns in the table, not just the one in the projection:
SELECT [t1].[Id], 开发者_如何转开发[t1].[Value], [t1].[timestamp], [t1].[etc...]
FROM [Entity] AS [t1]
So my question is, how do I encapsulate this projection without the LINQ to SQL instantiating the whole Entity?
Things to keep in mind, the DTO I am using has a protected default constructor, so I can't use an object initializer. And since the DTO class cannot be modified, I'd have to make a subclass to implement that behavior. Which is fine, if that's the only solution.
Thanks.
Edit:
Thanks to Brian for the solution. I had previously tried an Expression but couldn't figure out the syntax. Here's the working code:
Expression<Entity, DTO> ToDTO = (e) => new DTO(e.Value);
Then call it like this:
db.Entities.Select(ToDTO);
At first I was trying to call it like this, which wouldn't compile. This is the proper syntax for calling a Func, but not an Expression.
db.Entities.Select(e => ToDTO(e));
You probably need to create an Expression
, not a Func
Expression<Func<Entity, DTO>> ToDTO = (e) => new DTO(e.Value);
IQueryable extension methods work with Expression
s, not Func
s
By passing in a Func
, you are probably invoking the IEnumerable
extension method, which is why Linq2Sql is acting the way it is.
精彩评论