Reputation: 590
Using Entity Framework and LINQ, how might I achieve this TSQL:
SELECT Children.ChildCount, Parent.*
FROM Parent
LEFT JOIN (SELECT ParentID, COUNT(ChildID) AS ChildCount FROM Child GROUP BY ParentID) AS Children
ON Parent.ID = Children.ParentID
Note that this is just a small part of what is already a larger LINQ query that includes other related entities so using a RawSQL query is not an option. Also the Parent table has around 20 columns and I'm hoping not to have to specify each individually to keep the code maintainable.
EDIT: To clarify a couple of things, the model for the output of the query (very simplified) looks something like this:
public class MyEntity
{
public int ID {get; set;}
public string Name {get; set;}
public int ChildCount {get; set;}
// many other properties here including related records
}
So what I'm trying to do is get the ChildCount included in the result of the query so it is included in the EF entity.
Upvotes: 0
Views: 719
Reputation: 590
For anyone who comes across this at a later date, I ended up using AutoMapper as suggested by Nik P (I was already using AutoMapper anyway) to map from db entities to DTOs.
In effect, in my AutoMapper mapping I have:
CreateMap<MyEntity, MyEntityDTO>()
.ForMember(d => d.ChildCount, opt => opt.MapFrom(src => src.ChildEntity.Count()))
Then in my Service layer I call:
IEnumerable<MyEntityDTO> results = await dbContext.MyEntities.ProjectTo<MyEntityDTO>(mapper.ConfigurationProvider).ToListAsync();
Upvotes: 1
Reputation: 3093
You can use a Select Query to project the DB info onto an entity, something like:
var entity = db.Parent.Select(x =>
new MyEntity
{
Id = x.Id,
Name = x.Name,
ChildCount = x.Children
.Select(y => y.ParentId == x.Id)
.Count()
})
.SingleOrDefault(x => x.Id == IDYouNeedToQuery);
}
What this should do is return you 1 instance of your MyEntity
class with the Name, ID, and ChildCount properties filled in. Your SQL won't quite match what is generated but this should get you what you want. BTW you can also sub the SingleOrDefault
line with a filter of another type, or no filter in which case the entity
variable becomes a collection of MyEntity
.
For further reading on this technique and how to use AutoMapper to make it super easy to set up, check out this post from Jon P Smith, who literally wrote the book on Entity Framework Core.
Hope this helps.
Upvotes: 1