c# - 在 EF Core 中按孙子属性过滤父集合

标签 c# entity-framework asp.net-core linq-to-entities

使用 EF core 5 和 ASP.NET Core 3.1,我尝试根据其孙子集合的条件获取过滤后的集合。 我有以下实体:

public class Organisation
{
        public int Id { get; set; }
        public int? OrganisationId { get; set; }
        public IEnumerable<Customer> Customers { get; set; }
}

public partial class Customer
{
        [Key]
        public uint Id { get; set; }
        public int? EmployerId { get; set; }
        public int? OrganisationId { get; set; }
        public List<TimecardProperties> TimecardsProperties { get; set; }
}

public partial class TimecardProperties
{     
        [Key]
        public int Id { get; set; }
        public int? EmployerId { get; set; }
        public int? Week { get; set; }
        public short? Year { get; set; }
}

目标是让所有组织至少拥有一名客户,并且该客户至少拥有 1 个位于 week=34year=2021 的考勤卡属性。

到目前为止,我已经尝试过以下方法:

////necessary join to get Organisations for user id
            IQueryable<Organisation> ouQuery = (from cou in _dbContext.Organisations
                           join uou in _dbContext.table2 on cou.OrganisationId equals uou.OrganisationId                           
                           where uou.UsersId == int.Parse(userId)                          
                           select cou)
                           .Where(cou => cou.Customers.Where(c => c.TimecardsProperties.Count > 0).Any())
                           .Include(cou => cou.Customers.Where(c => c.TimecardsProperties.Count > 0))
                        .ThenInclude(c => c.TimecardsProperties.Where(tc => tc.tWeek == 34 && tc.Year > 2020))
                             ;

这会返回一个组织列表,每个列表都有一个客户列表,但有些客户的时间卡计数为0。我不希望返回列表中的 organizationtimecards 集合中至少没有一项。

此外,它太慢了,如果我尝试过滤生成的列表,它甚至 较慢(超过 15 秒)

我还在组织数据库上下文上尝试了原始sql查询,但它再次非常慢:

select distinct count(id) from organisation a where organisation_id  in (
select organisation_id from customers where employer_id in (select distinct employer_id from timecards a
inner join timecard_components b on a.id=b.timecards_id
where week IN(
34) and year in (2021,2021) and invoice !=0 and type = 'time'
 group by employer_id, week)
);

总的来说,我想知道总数 返回的用于分页的 organization 集合的计数(因此我不需要包含每个实体的所有属性) 以及仅返回满足条件的部分正确结果, 一个组织列表,其中至少有 1 个考勤卡 他们的客户通过最后执行查询如下:

ouQuery.Skip((page - 1) * pageSize).Take(pageSize).ToListAsync();

我也尝试过 EntityFramework.Plus 和投影,但没有结果。 我该如何编写此代码以获取 organization 列表的总数以及向用户显示的部分结果(前 10 个)?

最佳答案

使用导航属性。这是您想要的查询:

var orgsQuery = dbContext.Organizations
    .Where( o => o.Customers.Any( c =>
        c.TimecardProperties.Any( tp =>
            tp.Year = 2021
            && tp.Week = 34 ) ) );

根据需要添加包含和其他谓词

关于c# - 在 EF Core 中按孙子属性过滤父集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70735098/

相关文章:

c# - 复选框 CheckedChanged 事件

c# - 如何从 SQL Server 向 c# 控制台应用程序发出信号?

c# - DbContext 加载缓慢

c# - 为什么 Culture Info 在 .NET Core MVC 中的 Controller 和 View 中不同

c# - 如何在 ASP.NET Core 中手动生成防伪 token

c# - NUnit visual studio 扩展的混合模式错误

c# - 如何在 WCF 中使用 DomainModel

c# - 预编译 View 不影响性能

c# - 错误 - 无法加载具有固定名称 'System.Data.SQLite.EF6' 的 ADO.NET 提供程序

asp.net-core - 使用 PropertyBuilder.HasValueGenerator 并连接到数据库上下文