c# - 从存储过程结果创建对象

标签 c# sql-server linq stored-procedures

我们有一个带有以下查询的现有 SQL Server 存储过程。我们需要在以下类设计中根据查询结果创建一个 Student 对象集合。

使用 LINQSqlDataReader 创建对象的最佳方法是什么?

注意:我只使用SqlDataReader;没有 ORM

查询

SELECT 
    S.StudentID, S.StudentName, E.ExamID, E.ExamName, SE.Mark 
FROM 
    StudentExam SE
INNER JOIN 
    Student S ON S.StudentID = SE.StudentID
INNER JOIN 
    Exam E ON E.ExamID = SE.ExamID 

public class ExamMark
{
    public int ExamID { get; set; }
    public string ExamName { get; set; }
    public int Mark { get; set; }
}

public class Student
{
    public int StudentID { get; set; }
    public string StudentName { get; set; }
    public List<ExamMark> examResults { get; set; }
}

SQLDataReader

   SqlDataReader reader = command.ExecuteReader();
   if (reader.HasRows)
   {
      while (reader.Read())
      {

      }
   } 

引用文献

  1. LINQ: Fill objects from left join
  2. Complex GROUP BY on DataTable

最佳答案

我不会那样做的,

我有两个陈述

-- Student Statement
SELECT
             S.StudentID,
             S.StudentName
    FROM
             Student S
    WHERE
             EXISTS (
              SELECT * FROM StudentExam SE WHERE SE.StudentID = S.Student.ID);

-- Exam Statement
SELECT
            SE.StudentID,
            E.ExamID,
            E.ExamName,
            SE.Mark 
    FROM
            StudentExam SE
        JOIN
            Exam E
                ON E.ExamID = SE.ExamID;

然后,我有一个函数可以做到这一点,

private IEnumerable<Tuple<int, ExamMark>> GetMarks()
{
    ... setup the exam command here
    var reader = examCommand.ExecuteReader();
    while (reader.Read())
    {
        yield return Tuple.Create(
            reader.GetInt32(0),
            new ExamMark
                {
                    reader.GetInt32(1),
                    reader.GetString(2),
                    reader.GetInt32(3)
                });
    }
}

然后我可以调用这个函数,

private IEnumerable<Student> GetStudents()
{
    var resultLookup = GetMarks().ToLookup(t => t.Item1, t => t.Item2);

    ... setup the student command here
    var reader = studentCommand.ExecuteReader();
    while (reader.Read())
    {
        var studentId = reader.GetInt32(0);
        yield return new Student
                {
                    studentId,
                    reader.GetString(1),
                    resultLookup[studentId].ToList()
                });
    }
}

如果需要,您可以在一个存储过程中完成所有操作并返回多个结果集。

关于c# - 从存储过程结果创建对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17649415/

相关文章:

sql-server - 组的平均值不正确

c# - 如何使用 LINQ 重命名列表中的重复项

c# - C# 实践练习(学习路径)

c# - C 和 C# 中的加法赋值?

c# - 关于 NHibernate 的 GuidCombGenerator 的几个问题

php - 从 Php 5.5 访问 MS SQL

c# - LINQ连接两个表并返回列表

c# - 将另一个构建排队,然后等待构建完成

c# - 将更改后的元素保存回 XML 文件

c# - LINQ to Entities实体初始化