Reputation: 143
I'm using Entity Framework 6.x database first and a SQL Azure database.
I have a database table of Studies and a separate table of Respondents. In my EF designer, I have a Studies entity and Respondents entity and the Studies Entity has a Navigation Property for Respondents. Each study can have thousands of respondents and there are hundreds of studies.
My problem is that I'm trying to create a calculated column on the Studies table that contains the COUNT of Respondents and I'm trying to eager load this value. The reason that I need eager loading is because I'm populating a DataGrid (WPF) with the list of Studies and one of the columns in my grid is RespondentCount. If I don't eager load this value, then the scrolling on my data grid is janky as the RespondentCounts are lazy loaded when the user scrolls the grid.
I can certainly eager load all the respondents using this statement:
ctx.Studies.Include(s => s.Respondents)
and then do a .COUNT() on the Respondents Navigation property but then I'd be loading thousands of Respondents per Study which is a huge performance hit and a lot of wasted memory because all I need is the COUNT.
What I really need is:
ctx.Studies.Include(s => s.Respondents.Count)
But this doesn't work.
I tried setting up a Database VIEW that contains the Studies table with a simple calculated field for RespondentCount, but the VIEW is readonly in Entity Framework and I lose all my other foreign key relationships on the Studies table when I bring the VIEW into the EF designer.
How can I get this aggregate value eager loaded, without having to load all the respondents?
Upvotes: 1
Views: 1263
Reputation: 1667
Steps:
Studies
table to use that new function.HasDatabaseGeneratedOption
property with a parameter of DatabaseGeneratedOption.Computed
.Some potential code with my own test tables
create table respondents (id int, study_id int)
create function dbo.CountRespondents (@id int)
returns int
as
begin
return (select count(1) from respondents where study_id = @id)
END
create table studies (id int, name varchar(50), respondents as dbo.CountRespondents(id))
insert into respondents values (1, 1)
insert into respondents values (2, 1)
insert into respondents values (3, 1)
insert into respondents values (4, 2)
insert into respondents values (5, 2)
insert into studies values (1, 'Study 1')
insert into studies values (2, 'Study 2')
select * from studies
EF Code
ctx.Studies.Property(s => s.Respondents).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);
Instead of Include
, use Property
.
I can't really say if this would be performant enough for you since I don't know the volume - and I haven't actually tested the EF portion with the SQL I wrote. But I would imagine it should work fine.
Upvotes: 2