There is an entity type called product that is generated by entity framework. I have writen this query
public IQueryable<Product> GetProducts(int categoryID)
{
return from p in db.Products
where p.CategoryID== categoryID
select new Product { Name = p.Name};
}
The code below throws the following error :
"The entity or complex type Shop.Product cannot be constructed in a LINQ to Entities query"
var products = productRepository.GetProducts(1).Tolist();
But when I use select p
instead of select new Product { Name = p.Name};
it works correctly.
How can I preform a custom select section?
You cannot (and should not be able to) project onto a mapped entity. You can, however, project onto an anonymous type or onto a DTO:
public class ProductDTO
{
public string Name { get; set; }
// Other field you may need from the Product entity
}
And your method will return a List of DTO's.
public List<ProductDTO> GetProducts(int categoryID)
{
return (from p in db.Products
where p.CategoryID == categoryID
select new ProductDTO { Name = p.Name }).ToList();
}
I don't understand why I should not be able to do this... This would be very usefull...
Well, mapped entities in EF basically represent database tables. If you project onto a mapped entity, what you basically do is partially load an entity, which is not a valid state. EF won't have any clue how to e.g. handle an update of such an entity in the future (the default behaviour would be probably overwriting the non-loaded fields with nulls or whatever you'll have in your object). This would be a dangerous operation, since you would risk losing some of your data in the DB, therefore it is not allowed to partially load entities (or project onto mapped entities) in EF.
@Yakimych that makes sense except if you have some aggregate entity that you are generating/creating via a query and therefore are fully aware/intend to create a brand new entity that you will then manipulate and later add. In this case you either have to force run the query or push into a dto and back into an entity to add - which is frustrating
@Cargowire - I agree, that scenario exists, and it is frustrating when you know what you are doing but are not allowed to do it due to limitations. However, had this been allowed, there would be lots of frustrated developers complaining about their data getting lost when e.g. trying to save partially loaded entities. IMO, an error that blows up with a lot of noise (throwing an exception, etc) is better than behavior which can cause hidden bugs that are difficult to track down and explain (things kind of work nicely before you start noticing missing data).
D.T.O - Data Transfer Objects