LINQ OrderBy ThenByDescending 使用 C# 中两个表中的数据
LINQ OrderBy ThenByDescending using data from two tables in C#
我有一个 table Student
包含这些列:
ID (PK, bigint, not null)
Height (int, not null)
IQ (int, not null)
SchoolId (bigint, not null)
和一个 table School
列:
ID (PK, bigint, not null)
Charter (bit, not null) -- 1 means charter, 0 means not charter
我也有方法
private static IEnumerable<IStudent> SortStudentList(IEnumerable<IStudent> students)
{
return students.OrderBy(s => s.Height).ThenBy(s => s.IQ);
}
这很好用。但是现在,我还需要按宪章排序。在英语中,“按身高升序排序,然后按 Charter 降序排序(首先获得 Charter schools),然后按 IQ 升序排序”
类似于:
private static IEnumerable<IStudent> SortStudentList(IEnumerable<IStudent> students)
{
return students.OrderBy(s => s.Height).ThenByDescending(s => s.GetCharterStatus).ThenBy(s => s.IQ);
}
实体(我正在使用 Entity Framework)Student
确实有一个 link 到 School
通过
public class Student, IStudent
{
...
[Index(IsUnique = true)]
public long SchoolId { get; set; }
...
}
public interface IStudent
{
...
long SchoolId {get;set;}
...
}
奇怪的是,当我使用 SQLite/SQL Server Compact Toolbox 查看关系时,我没有看到 SchoolId 列表作为外键,而是在 Student table 的“Indexes”文件夹下它显示为
IX_SchoolId (Unique)
我在弄清楚如何获取查询的特许学校部分时遇到问题,并且尝试了各种方法。我需要以某种方式加入吗?
如果我可以澄清或提供更多信息,请告诉我。我正在使用 SQL Server CE 和 Entity Framework 尽管我怀疑这与问题无关。
谢谢,
戴夫
P.S。数据是为了保护公司机密而编造的,但关系是一样的。我对身高、智商和特许学校地位之间的关系没有任何看法:)
I'm having trouble figuring out how to get the Charter school part of the query and have tried various things. Do I need to somehow do a join?
是的,但是有几种方法可以执行此操作,具体取决于您是否使用 ORM。
基于SQL的方法
如果使用普通 SQL,您将需要连接两个表以提取所需的所有数据。查询可能看起来像这样:
SELECT
Students.*,
Schools.Charter
FROM
Students
INNER JOIN
Schools ON Students.SchoolId = Schools.Id
这将是 return 一组学生及其“特许学校名称”,可能如下所示:
public class StudentWithSchoolType
{
// Properties from Student
public int ID { get; set; }
public int Height { get; set; }
public int IQ { get; set; }
// Properties from Schools
public bool Charter { get; set; }
}
或者,如果您已经在 IStudent
的界面上拥有这些属性,它可能看起来更像:
public class StudentWithSchoolType : IStudent
{
// Student Properties inherited from IStudent
public bool Charter { get; set; }
}
如果您将始终执行此操作,您也可以将其包含在界面中,但您的需求可能会有所不同。
获得该数据后,您可以简单地访问需要独立订购的学生或学校数据,因为必要的字段应该是
private static IEnumerable<IStudent> SortStudentList(IEnumerable<IStudent> students)
{
return students.OrderBy(s => s.Height)
.ThenByDescending(s => s.Charter)
.ThenBy(s => s.IQ);
}
基于 ORM 的方法
如果您正在使用像 Entity Framework 这样的 ORM 并且在这两个表之间有关系(即学生 属性 上的学校),那么您可以通过 Include()
从数据库中提取时调用的方法:
// This will populate the School property of the Student with any
// properties it has
var students = YourContext.Students
.Include("School")
.ToList();
这将简化您的查询,因为您随后可以使用:
private static IEnumerable<IStudent> SortStudentList(IEnumerable<IStudent> students)
{
// Notice the use of s.School.Charter
return students.OrderBy(s => s.Height)
.ThenByDescending(s => s.School.Charter)
.ThenBy(s => s.IQ);
}
如果您还没有 School
对象,但有密钥,那么您只需要按如下方式将一个添加到您的 Student
实体中:
public class Student
{
// Your Student properties here
[Index(IsUnique = true)]
[ForeignKey("School")]
public long SchoolId { get; set; }
public virtual School School { get; set; }
}
另一种方式,通过添加扩展方法:
public static short GetCharterStatus(this IStudent student, )
{
return schools.First(school=> school.ID == student.SchoolId).Charter;
}
我有一个 table Student
包含这些列:
ID (PK, bigint, not null)
Height (int, not null)
IQ (int, not null)
SchoolId (bigint, not null)
和一个 table School
列:
ID (PK, bigint, not null)
Charter (bit, not null) -- 1 means charter, 0 means not charter
我也有方法
private static IEnumerable<IStudent> SortStudentList(IEnumerable<IStudent> students)
{
return students.OrderBy(s => s.Height).ThenBy(s => s.IQ);
}
这很好用。但是现在,我还需要按宪章排序。在英语中,“按身高升序排序,然后按 Charter 降序排序(首先获得 Charter schools),然后按 IQ 升序排序”
类似于:
private static IEnumerable<IStudent> SortStudentList(IEnumerable<IStudent> students)
{
return students.OrderBy(s => s.Height).ThenByDescending(s => s.GetCharterStatus).ThenBy(s => s.IQ);
}
实体(我正在使用 Entity Framework)Student
确实有一个 link 到 School
通过
public class Student, IStudent
{
...
[Index(IsUnique = true)]
public long SchoolId { get; set; }
...
}
public interface IStudent
{
...
long SchoolId {get;set;}
...
}
奇怪的是,当我使用 SQLite/SQL Server Compact Toolbox 查看关系时,我没有看到 SchoolId 列表作为外键,而是在 Student table 的“Indexes”文件夹下它显示为
IX_SchoolId (Unique)
我在弄清楚如何获取查询的特许学校部分时遇到问题,并且尝试了各种方法。我需要以某种方式加入吗?
如果我可以澄清或提供更多信息,请告诉我。我正在使用 SQL Server CE 和 Entity Framework 尽管我怀疑这与问题无关。
谢谢, 戴夫
P.S。数据是为了保护公司机密而编造的,但关系是一样的。我对身高、智商和特许学校地位之间的关系没有任何看法:)
I'm having trouble figuring out how to get the Charter school part of the query and have tried various things. Do I need to somehow do a join?
是的,但是有几种方法可以执行此操作,具体取决于您是否使用 ORM。
基于SQL的方法
如果使用普通 SQL,您将需要连接两个表以提取所需的所有数据。查询可能看起来像这样:
SELECT
Students.*,
Schools.Charter
FROM
Students
INNER JOIN
Schools ON Students.SchoolId = Schools.Id
这将是 return 一组学生及其“特许学校名称”,可能如下所示:
public class StudentWithSchoolType
{
// Properties from Student
public int ID { get; set; }
public int Height { get; set; }
public int IQ { get; set; }
// Properties from Schools
public bool Charter { get; set; }
}
或者,如果您已经在 IStudent
的界面上拥有这些属性,它可能看起来更像:
public class StudentWithSchoolType : IStudent
{
// Student Properties inherited from IStudent
public bool Charter { get; set; }
}
如果您将始终执行此操作,您也可以将其包含在界面中,但您的需求可能会有所不同。
获得该数据后,您可以简单地访问需要独立订购的学生或学校数据,因为必要的字段应该是
private static IEnumerable<IStudent> SortStudentList(IEnumerable<IStudent> students)
{
return students.OrderBy(s => s.Height)
.ThenByDescending(s => s.Charter)
.ThenBy(s => s.IQ);
}
基于 ORM 的方法
如果您正在使用像 Entity Framework 这样的 ORM 并且在这两个表之间有关系(即学生 属性 上的学校),那么您可以通过 Include()
从数据库中提取时调用的方法:
// This will populate the School property of the Student with any
// properties it has
var students = YourContext.Students
.Include("School")
.ToList();
这将简化您的查询,因为您随后可以使用:
private static IEnumerable<IStudent> SortStudentList(IEnumerable<IStudent> students)
{
// Notice the use of s.School.Charter
return students.OrderBy(s => s.Height)
.ThenByDescending(s => s.School.Charter)
.ThenBy(s => s.IQ);
}
如果您还没有 School
对象,但有密钥,那么您只需要按如下方式将一个添加到您的 Student
实体中:
public class Student
{
// Your Student properties here
[Index(IsUnique = true)]
[ForeignKey("School")]
public long SchoolId { get; set; }
public virtual School School { get; set; }
}
另一种方式,通过添加扩展方法:
public static short GetCharterStatus(this IStudent student, )
{
return schools.First(school=> school.ID == student.SchoolId).Charter;
}