我们有一个带有以下查询的现有 SQL Server 存储过程。我们需要在以下类设计中根据查询结果创建一个 Student
对象集合。
使用 LINQ
从 SqlDataReader
创建对象的最佳方法是什么?
注意:我只使用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())
{
}
}
引用文献
最佳答案
我不会那样做的,
我有两个陈述
-- 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/