LINQ 多个“||”带“&”运算符

LINQ Multiple "||" with "&" operator

我有以下 Linq 查询试图过滤满足特定条件的结果集合,如下所示:

public async Task<BillListResponse> GetStudentCurrentBillsAsync(Student student)
    {
        var studentEvents = student.StudentEvents;
        var studentServices = student.StudentServices;
        var studentGroups = student.StudentGroups;

List<Bill> currentBills = await _context.Bills
            .Include(b => b.Category)
            .Where(b => ((b.ClassBills.Any(c => c.StudentClassId == student.ClassId)) || studentGroups.Any(sg => sg.SpecialGroupId == b.GroupId) || studentServices.Any(ss => ss.SpecialServiceId == b.ServiceId) || b.CareerPathBills.Any(cpb => cpb.CareerPathId == student.CareerPathId)) && b.SessionId == currentSession.Id
                ).ToListAsync();
......

但是我不断收到以下错误

InvalidOperationException: The LINQ expression 'DbSet .Where(b => DbSet .Where(c => EF.Property>(b, "Id") != null && EF.Property>(b, "Id") == EF.Property>(c, "BillId")) .Any(c => c.StudentClassId == __student_ClassId_0) || __student_StudentEvents_1 .Any(se => (Nullable)se.EventId == b.EventId) || __student_StudentGroups_2 .Any(sg => (Nullable)sg.SpecialGroupId == b.GroupId) || __student_StudentServices_3 .Any(ss => (Nullable)ss.SpecialServiceId == b.ServiceId) || DbSet .Where(c0 => EF.Property>(b, "Id") != null && EF.Property>(b, "Id") == EF.Property>(c0, "BillId")) .Any(c0 => (Nullable)c0.CareerPathId == __student_CareerPathId_4) && b.SessionId == __currentSession_Id_5)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync().

我没能解决。 但是,我意识到如果删除“||”表达式中的子句,如下:

List<Bill> currentBills = await _context.Bills
            .Include(b => b.Category)
            .Where(b => b.ClassBills.Any(c => c.StudentClassId == student.ClassId) && b.SessionId == currentSession.Id
                ).ToListAsync();

它有效,但我需要完整表达式中表达的更多条件。

我在 运行 ASP.NET-Core 3.1 Windows 上 SQL 服务器数据库。

“||”似乎有问题操作员。

请指导我解决这个问题。我会感激的。

谢谢

更新


实体关系如下:

学生实体有以下内容

public virtual ICollection<StudentGroup> StudentGroups { get; set; }
public virtual ICollection<StudentService> StudentServices { get; set; }

public virtual ICollection<StudentEvent> StudentEvents { get; set; }

并且还存在以下 DbSet

public DbSet<StudentGroup> StudentGroups { get; set; }
public DbSet<StudentEvent> StudentEvents { get; set; }
public DbSet<SpecialService> Services { get; set; }

而多对多中间表如下

public class StudentEvent
{
    public string StudentId { get; set; }
    public int EventId { get; set; }

    [ForeignKey("StudentId")]
    public Student Student { get; set; }
    [ForeignKey("EventId")]
    public SchoolEvent Event { get; set; }
}

public class StudentService
{
    public int SpecialServiceId { get; set; }
    public virtual SpecialService Service { get; set; }
    public string StudentId { get; set; }
    public virtual Student Student { get; set; }
}

public class StudentGroup
{
    public int SpecialGroupId { get; set; }
    public virtual SpecialGroup SpecialGroup { get; set; }
    public string StudentId { get; set; }
    public virtual Student Student { get; set; }
}

更新

我已经按如下方式修改了查询,它现在似乎可以正常工作了。

var studentEvents = student.StudentEvents.ToList();
var studentServices = student.StudentServices.ToList();
var studentGroups = student.StudentGroups.ToList();

List<Bill> bills = await (from b in _context.Bills where b.ClassBills.Any(c => c.StudentClassId == student.ClassId) || (studentEvents.Any() && studentEvents.Any(se => se.EventId == b.EventId)) || (studentGroups.Any() && studentGroups.Any(sg => sg.SpecialGroupId == b.GroupId)) || (studentServices.Any() && studentServices.Any(ss => ss.SpecialServiceId == b.ServiceId)) || b.CareerPathBills.Any(cpb => cpb.CareerPathId == student.CareerPathId) select b).ToListAsync();

另一种似乎按预期工作的方式如下

var studentEvents = student.StudentEvents.ToList();
var studentServices = student.StudentServices.ToList();
var studentGroups = student.StudentGroups.ToList();

var currentBills = _context.Bills
            ?.Include(b => b.Category)
            ?.Include(b => b.ClassBills)
            ?.Include(b=>b.CareerPathBills)
            ?.Where(b => b.SessionId == currentSession.Id);

        if (student.StudentEvents.Any())
        {
            currentBills = currentBills.Where(b => student.StudentEvents.Any(se => se.EventId == b.EventId));
        }

        if (student.StudentServices.Any())
        {
            currentBills = currentBills.Where(b => student.StudentServices.Any(se => se.SpecialServiceId == b.ServiceId));
        }

        if (student.StudentGroups.Any())
        {
            currentBills = currentBills.Where(b => student.StudentGroups.Any(se => se.SpecialGroupId == b.GroupId));
        }

        var currentBillsList = await currentBills.ToListAsync();

currentBillsList

是 return

的预期结果

我不确定这是否是正确的方法。

失败的原因是 students 集合可能不是 SQL 数据库表查询的一部分,即调用 ToListToListAsync 它正在成为 C# 实体集合,不能与 LINQ to Entities 集合一起使用。

Hint: make sure that your students are collections of IQuerable.

但是,作为替代建议,您可以使用 Join Students 和 Bills,而不是在 Where 子句中使用过滤。