对Linq查询进行排序

时间:2018-11-05 19:35:37

标签: c# entity-framework linq

我正在尝试使用表中的优先级字段对以下Linq查询进行排序。

foreach (var faculty in specialty.faculty_specialties.Where(f => f.faculty.active))

我尝试将.OrderByDescending(p => p.priority)添加到末尾,但没有成功。 我在MVC项目中使用C#和Visual Studio。谢谢

1 个答案:

答案 0 :(得分:0)

首先将逻辑分解为单独的操作,而不是尝试将所有内容写成一行。编译器是智能Cookie,因此它们可以很好地优化内容,没有任何意义使您的代码难以阅读/理解:

var facultySpecialties = specialty.faculty_specialties
  .Where(fs => fs.faculty.active)
  .ToList(); // Executes the query to retrieve faculty specialties.

foreach(var facultySpecialty in facultySpecialties)
{
  // do stuff.
}

请注意查询中要引用的实体的范围。上面的查询将返回faculty_specialties,而不是faculties。要提防的陷阱:由于这将返回fac_specs,因此,如果要在feach循环中访问fac_spec和教师的详细信息,请同时包含该教师。

var facultySpecialties = specialty.faculty_specialties
  .Include(fs => fs.faculty)
  .Where(fs => fs.faculty.active)
  .ToList(); 

如果您只想学系,并且不需要来自fac_spec的信息:

var faculties = specialty.faculty_specialties
  .Select(fs => fs.faculty)
  .Where(f => f.active)
  .ToList();

这将从我们的fac_specs中选择教师。请注意,Where子句会发生变化,因为.Select()之后的范围将变为Faculties,而不是Faculty_Specialities。如果仍然需要fac_specs的详细信息,则可以使用.Include(f => f.faculty_specialties),但是如果不需要则不包含关系,因为这会增加查询的性能成本和传输成本(大小)。

现在,您需要订购教师。问题是优先权适用于哪个实体?如果“优先级”是教师领域,则:

var faculties = specialty.faculty_specialties
  .Select(fs => fs.faculty)
  .Where(f => f.active)
  .OrderBy(f => f.Priority)
  .ToList();

但是,我怀疑优先级是在faculty_speciality上。

如果您具有从教师回到faculty_specialities的导航属性(我假设是多对多的关系,那么教师可以映射ICollection<faculty_specialities>),而在您的上下文中,教师是DbSet,那么您可能想要重组查询,因为这将使订购更加容易:

var faculties = dbContext.Faculties
  .Where(f => f.active && f.faculty_specialties.Any(fs => fs.specialty.specialtyId == specialty.specialtyId))
  .ToList();

要通过faculty_speciality.priority实施订单:

var faculties = dbContext.Faculties
  .Where(f => f.active 
    && f.faculty_specialties.Any(fs => fs.specialty.specialtyId == specialty.specialtyId))
  .OrderByDescending(f => f.faculty_specialties.Min(fs => fs.priority))
  .ToList();

您可以尝试对原始查询进行排序,例如:

var faculties = specialty.faculty_specialties
  .OrderBy(fs => fs.priority)
  .Select(fs => fs.faculty)
  .Where(f => f.active)
  .ToList();

但是我不确定这种排序是否会遵循最终结果集。

像这样的查询要考虑的最后一件事是,随着系统的增长,随着给定专业的设施数量的增加,数据量可能会使这样的操作变得非常昂贵。您应该考虑在使用.Take().Skip()时就对结果大小和分页支持施加限制,除非系统的大小将被限制在合理的数量之内。