SQL->;LINQ(C#)

SQL->;LINQ(C#),c#,sql,linq,C#,Sql,Linq,我有一个SQL查询(如下所示),它从tbStudents中获取一个student,然后获取tbTerms中最新的术语(一个数字,但存储为字符串) 在tbTerms中,学生与学生之间存在一对多的关系,在tbTerms中,学生与学期记录之间存在一对多的关系。例如: 学生: StudentId FirstName LastName 12345 John Smith 12346 Jane Doe 技术条款: StudentId Term 12345 1234

我有一个SQL查询(如下所示),它从tbStudents中获取一个student,然后获取tbTerms中最新的术语(一个数字,但存储为字符串)

在tbTerms中,学生与学生之间存在一对多的关系,在tbTerms中,学生与学期记录之间存在一对多的关系。例如:

学生:

StudentId FirstName LastName
12345     John      Smith
12346     Jane      Doe
技术条款:

StudentId Term
12345     1234
12345     1235
12345     1236
12346     1233
12346     1234
期望的:

StudentId FirstName LastName Term
12345     John      Smith    1236
12346     Jane      Doe      1234
SQL查询:

select tbStudents.student_id, tbStudents.user_id, tbStudents.firstname, tbStudents.lastname, v.rTerm
    from  tbStudents
    inner join (
        select tbTerms.student_id, MAX(tbTerms.term) as rTerm
        from tbTerms
        group by tbTerms.student_id
    ) v on v.student_id = tbStudents.student_id
我一直试图把这一切都写进一个LINQ声明中,但我遇到了麻烦。在一份声明中是否有这样做的必要?或者必须在多个语句中完成。提前谢谢

编辑:我尝试过的代码

var students = (from s in dockDb.tbStudents
                join t in dockDb.tbTerms on s.student_id equals t.student_id
                into pairs
                from p in pairs
                select new { UserId = s.user_id, StudentId = s.student_id, Term = p.term } ).ToList();
输出类似于:

StudentId FirstName LastName Term
12345     John      Smith    1234
12345     John      Smith    1235
12345     John      Smith    1236
12346     Jane      Doe      1233
12346     Jane      Doe      1234

编辑#2:我正在对数据使用实体框架。我不确定这是否会影响什么,但当我尝试这些解决方案时,大多数解决方案都是“语法错误的”。

您应该尝试类似的方法:

from s in dockDb.tbStudents
join t in dockDb.tbTerms on t.student_id equals s.student_id into st
group st by New {StudentID = st.student_id, Term = t.term} into g
select New { g.Key, g.Max(i => i.Term) }

不知何故,我一直认为扩展方法的语法更具可读性和自然性。下面是:

context.Students.Select(s => new
{
    s.StudentId,
    s.FirstName,
    s.LastName,
    Term = context.Terms.Where(t => t.StudentId == s.StudentId)
                        .Select(t => t.TermNumber)
                        .OrderByDescending(t => t)
                        .First()
});

基本上,对于每个学生,它选择他/她的所有术语,从最近到最不最近排序,并在结果中包括第一个(最近的)。

应该是可能的。试试这个:

from s in Students
join t in Terms on t.StudentId = s.StudentId
select new {Student = s, Term = t}
group by s into g
select new {g.Key.StudentId, g.Key.FirstName, g.Key.LastName, g.Max(x=>x.Term.term)};
将其分解,前两行定义要搜索的域;即学生与词汇的内在联结组合,由学生ID联结。Student和Term的每个唯一组合都被放入一个匿名类型中,然后这些实例由每个唯一的Student分组到一个查找中(键引用的IEnumerables的只读集合)。在中,我们可以选择关键的(学生的)重要信息,并在术语列表中找到具有最高值的(将是最新的)。

是您的朋友。让我们简单地按学生id将数据分组,然后将其投影到一个新表单。这是一个linqpad示例:

void Main()
{
    var students = new List<Student>()
    {
      new Student() { StudentID = 12345, Name = "Smith" },
      new Student() { StudentID = 12346, Name = "Jones" }
      };

    var terms = new List<Term>()
    {
        new Term() { StudentID=12345, TermID = 1234 },
        new Term() { StudentID=12345, TermID = 1235 },
        new Term() { StudentID=12345, TermID = 1236 },
        new Term() { StudentID=12345, TermID = 1237 },
        new Term() { StudentID=12346, TermID = 1233 },
        new Term() { StudentID=12346, TermID = 1234 },
    };

    var result = terms.GroupBy (tm => tm.StudentID)
                      .Select (gr => new
    {
        Name = students.First (s => s.StudentID == gr.Key).Name,
        Terms = gr.Select (g => g.TermID)
    });


    result.Dump();

}

// Define other methods and classes here
    public class Student
    {
        public int StudentID { get; set; }
        public string Name { get; set; }
    }

    public class Term
    {
        public int StudentID { get; set; }
        public int TermID { get; set; }
    }
void Main()
{
var students=新列表()
{
new Student(){StudentID=12345,Name=“Smith”},
new Student(){StudentID=12346,Name=“Jones”}
};
var terms=新列表()
{
新术语(){StudentID=12345,TermID=1234},
新术语(){StudentID=12345,TermID=1235},
新术语(){StudentID=12345,TermID=1236},
新术语(){StudentID=12345,TermID=1237},
新术语(){StudentID=12346,TermID=1233},
新术语(){StudentID=12346,TermID=1234},
};
var result=terms.GroupBy(tm=>tm.StudentID)
.选择(gr=>new
{
Name=students.First(s=>s.StudentID==gr.Key).Name,
术语=组选择(g=>g.TermID)
});
result.Dump();
}
//在此处定义其他方法和类
公立班学生
{
公共int StudentID{get;set;}
公共字符串名称{get;set;}
}
公共类术语
{
公共int StudentID{get;set;}
公共int TermID{get;set;}
}
以下是可以使用的输出:


你能展示你已经拥有的吗?“语法错误”。调用扩展名AsEnumerable()。我不得不修改代码中的一些内容使其运行,但除此之外,您的结构正是我所需要的。谢谢