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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With