LINQ OrderBy ThenByDescending使用C#中两个表的数据

时间:2017-03-10 21:08:20

标签: c# sql linq sql-server-ce

我有一张桌子学生 有字段

ID (PK, bigint, not null)
Height (int, not null)
IQ (int, not null)
SchoolId (bigint, not null)

和一个表学校 有字段

ID (PK, bigint, not null)
Charter (bit, not null)   -- 1 means charter, 0 means not charter

我有一个方法

private static IEnumberable<IStudent> SortStudentList(IEnumerable<IStudent> students)
{
    return students.OrderBy(s => s.Height).ThenBy(s => s.IQ);
}

这很有效。但是,现在我需要按照宪章进行排序。在英语中,&#34;按升序排序,然后按降序宪章(首先获得宪章学校),然后通过提升智商&#34;

类似的东西:

private static IEnumberable<IStudent> SortStudentList(IEnumerable<IStudent> students)
{
    return students.OrderBy(s => s.Height).ThenByDescending(s => s.GetCharterStatus).ThenBy(s => s.IQ);
}

实体(我使用EntityFramework)学生确实有一个学校链接

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列表视为外键,而是在&#34; Indexes&#34;学生表的文件夹,显示为

IX_SchoolId (Unique)

我无法弄清楚如何让宪章学校成为查询的一部分,并尝试过各种各样的事情。我需要以某种方式加入吗?

如果我能澄清或提供更多信息,请告诉我。我使用的是SQL Server CE和EntityFramework,但我怀疑这与问题无关。 谢谢, 戴夫

P.S。这些数据用于保护公司机密,但关系是相同的。我对高度,智商和特许学校地位之间的关系一无所知:)

2 个答案:

答案 0 :(得分:3)

  

我无法弄清楚如何让宪章学校成为查询的一部分,并尝试了各种各样的事情。我需要以某种方式加入吗?

是的,但是您可以通过几种方式进行此操作,具体取决于您是否使用ORM。

基于SQL的方法

如果使用纯SQL,则需要连接这两个表来提取所需的所有数据。查询可能如下所示:

    SELECT Students.*,
           Schools.Charter           
      FROM Students
INNER JOIN Schools ON Students.SchoolId = Schools.Id

这将返回一系列学生及其“特许学校指定”,可能如下所示:

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 IEnumberable<IStudent> SortStudentList(IEnumerable<IStudent> students)
{
    return students.OrderBy(s => s.Height)
                   .ThenByDescending(s => s.Charter)
                   .ThenBy(s => s.IQ);   
}

基于ORM的方法

如果您正在使用类似于实体框架的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 IEnumberable<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; }
}

答案 1 :(得分:1)

另一种方法是,通过添加扩展方法:

<asp:ListView runat="server" ID="lvLabels" ItemType="ServiceLayer.Models.AnsattOrderSummary">
        <ItemTemplate>
            <div class="lbl">
                <span class="lbl-inner">
                    <div class="col-sm-12">
                        <span>
                            <%# Item.OrderedBy %> ( <%# Item.AnsattNr %> )
                        </span>
                    </div>
                </span>
            </div>
            <div class="spc">&nbsp;</div>  This must be hidden for every 3'rd item.
        </ItemTemplate>
    </asp:ListView>