【问题标题】:Entity Framework database first aggregate column with eager loadingEntity Framework 数据库第一个聚合列与预加载
【发布时间】:2014-11-05 17:40:03
【问题描述】:

我首先使用的是 Entity Framework 6.x 数据库和一个 SQL Azure 数据库。

我有一个 Studies 数据库表和一个单独的 Respondents 表。在我的 EF 设计器中,我有一个 Studies 实体和 Respondents 实体,并且该 Studies 实体有一个针对 Respondents 的导航属性。每项研究可以有数千名受访者,并且有数百项研究。

我的问题是我试图在 Studies 表上创建一个计算列,其中包含 COUNT 的受访者,并且我试图急切地加载这个值。我需要预先加载的原因是因为我正在使用研究列表填充 DataGrid (WPF),并且我的网格中的列之一是 RespondentCount。如果我不急于加载这个值,那么我的数据网格上的滚动会很卡,因为当用户滚动网格时 RespondentCounts 会延迟加载。

我当然可以使用以下语句加载所有受访者:

ctx.Studies.Include(s => s.Respondents)

然后在 Respondents Navigation 属性上执行 .COUNT(),但我会为每个研究加载数千个 Respondents,这是一个巨大的性能损失和大量内存浪费,因为我只需要 COUNT。

我真正需要的是:

ctx.Studies.Include(s => s.Respondents.Count)

但这不起作用。

我尝试设置一个包含 Studies 表的数据库视图,其中包含一个简单的 RespondentCount 计算字段,但 VIEW 在实体框架中是只读的,当我将 VIEW 带入时,我丢失了 Studies 表上的所有其他外键关系EF 设计师。

如何在无需加载所有受访者的情况下快速加载此聚合值?

【问题讨论】:

    标签: c# sql-server entity-framework entity-framework-6


    【解决方案1】:

    步骤:

    1. 创建一个 SQL 用户定义函数,按研究统计受访者。
    2. 在您的 Studies 表中创建一个计算列以使用该新函数。
    3. 在您的 EF 映射中,添加新的计算列并使用 DatabaseGeneratedOption.Computed 参数设置 HasDatabaseGeneratedOption 属性。

    我自己的测试表的一些潜在代码

    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 代码

    ctx.Studies.Property(s => s.Respondents).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);
    

    请使用Property,而不是Include

    我真的不能说这对你来说是否足够高效,因为我不知道音量 - 而且我还没有使用我编写的 SQL 实际测试过 EF 部分。但我想它应该可以正常工作。

    【讨论】:

    • 太棒了!每天学些新东西。谢谢!
    猜你喜欢
    • 2019-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-27
    • 1970-01-01
    • 1970-01-01
    • 2014-07-24
    • 1970-01-01
    相关资源
    最近更新 更多