填充 A Class,其中另一个 class 作为 属性
populating A Class that has another class as a property
我的 windows 表单申请中有两个 class。
假设 Student
和 StudentDetails
其中 class StudentDetails
也是 Student
class.[=20= 的 属性 ]
我有一个存储过程,它从数据库中的两个表中获取数据。
我需要知道这种情况通常是如何处理的,这意味着 Student Class 通常是如何填充的。
非常感谢你的回答。
任何 link 类似的场景都很棒。
这是我的代码:
class Student
{
public int StudentID { get; set; }
public string StudentName { get; set; }
public StudentDetails StudentDetails { get; set; }
public Student()
{
this.StudentID = 0;
this.StudentName = String.Empty;
this.StudentDetails = new StudentDetails();
}
}
class StudentDetails
{
public int StudentDetailsID { get; set; }
public string Address { get; set; }
public int Height { get; set; }
public int Weight { get; set; }
public StudentDetails()
{
this.StudentDetailsID = 0;
this.Address = String.Empty;
this.Height = 0;
this.Weight = 0;
}
}
下面的class有一个函数是填充Student Class (FillStudent() )
Class StudentAssembler
{
public List<Model.Student> FillStudent()
{
List<Model.Student> StudentCollection = new List<Model.Student>();
Model.Student StudentDTO = new Model.Student();
try
{
using (Model.dbConnection dbconnection = new Model.dbConnection(Utilities.SqlConnStr))
{
SqlDataReader dr;
SqlCommand command = new SqlCommand("GetStudents", dbconnection.connection);
command.CommandType = CommandType.StoredProcedure;
dbconnection.OpenConn();
dr = command.ExecuteReader();
while (dr.Read())
{
StudentDTO.StudentID = dr[0] == DBNull.Value ? 0 : (int)dr[0];
StudentDTO.StudentName = dr[1] == DBNull.Value ? String.Empty : (String)dr[1];
//this is the part that i need to know how is it usually handled
//StudentDTO.StudentDetails = how to fill out this part ???
StudentCollection.Add(StudentDTO);
}
return StudentCollection;
}
}
catch (Exception)
{
return null;
}
}
}
编辑:
存储过程代码
select s.StudentID,s.StudentName,sd.StudentDetailsID,sd.Address,
sd.Height,sd.Weight
from Student s,StudentDetails sd
where s.StudentID = sd.StudentID
你有两个选择
1:一个单独的 sproc(或 sql)通过学生 ID 从学生详细信息 table 获取信息。每个学生都这样称呼
2:在您的 sproc/sql 中加入学生详细信息 table 并使用同一行数据填充两者
选项 1:通常更清洁且更可重用。我会说这应该是您的第一种方法。
但是,如果您需要检索很多学生,选项 2 会快得多。因为它只需要调用一次数据库。
而且你似乎在学生和学生细节之间有一对一的关系,所以没有理由不使用选项 2。但是如果你有一个学生的很多细节,你仍然可以使用选项 2,跳过重复的学生信息。这通常是最好的方法,即使您返回的数据多于 sql
所需的数据
考虑到存储过程查询,您可以简单地:
StudentDTO.StudentDetails = new StudentDetails
{
StudentDetailsID = dr[2] == DBNull.Value ? 0 : (int)dr[2],
Address = dr[3] == DBNull.Value ? String.Empty : (String)dr[3],
...
};
您可以创建单独的函数来获取学生和学生详细信息记录。
这样您就可以在代码中的任何地方重复使用这些函数。
例如对于 student
你可以有这样的函数
public Student CreateStudent(IDataRecord iDataRecord)
{
Student stud = new Student();
stud.Id = GetValue<int>(iDataRecord, "Id");
stud.Name = GetValue<string>(iDataRecord, "Name");
return stud;
}
对于 studentDetails
,创建如下函数:
public StudentDetails CreateStudentDetails(IDataRecord iDataRecord)
{
StudentDetails studDetails = new StudentDetails();
studDetails.Id = GetValue<int>(iDataRecord, "Id");
studDetails.Address = GetValue<string>(iDataRecord, "Address");
studDetails.Height = GetValue<string>(iDataRecord, "Height");
studDetails.Weight = GetValue<string>(iDataRecord, "Weight");
return studDetails;
}
然后,在您的 FillStudent
方法中,只需调用:
Student student=this.CreateStudent(dr);
student.StudentDetails=this.CreateStudentDetails(dr);
请注意,此代码仅用于说明目的。您可以进一步重构此代码以将其单独放置以创建工厂 类。
我的 windows 表单申请中有两个 class。
假设 Student
和 StudentDetails
其中 class StudentDetails
也是 Student
class.[=20= 的 属性 ]
我有一个存储过程,它从数据库中的两个表中获取数据。 我需要知道这种情况通常是如何处理的,这意味着 Student Class 通常是如何填充的。 非常感谢你的回答。 任何 link 类似的场景都很棒。
这是我的代码:
class Student
{
public int StudentID { get; set; }
public string StudentName { get; set; }
public StudentDetails StudentDetails { get; set; }
public Student()
{
this.StudentID = 0;
this.StudentName = String.Empty;
this.StudentDetails = new StudentDetails();
}
}
class StudentDetails
{
public int StudentDetailsID { get; set; }
public string Address { get; set; }
public int Height { get; set; }
public int Weight { get; set; }
public StudentDetails()
{
this.StudentDetailsID = 0;
this.Address = String.Empty;
this.Height = 0;
this.Weight = 0;
}
}
下面的class有一个函数是填充Student Class (FillStudent() )
Class StudentAssembler
{
public List<Model.Student> FillStudent()
{
List<Model.Student> StudentCollection = new List<Model.Student>();
Model.Student StudentDTO = new Model.Student();
try
{
using (Model.dbConnection dbconnection = new Model.dbConnection(Utilities.SqlConnStr))
{
SqlDataReader dr;
SqlCommand command = new SqlCommand("GetStudents", dbconnection.connection);
command.CommandType = CommandType.StoredProcedure;
dbconnection.OpenConn();
dr = command.ExecuteReader();
while (dr.Read())
{
StudentDTO.StudentID = dr[0] == DBNull.Value ? 0 : (int)dr[0];
StudentDTO.StudentName = dr[1] == DBNull.Value ? String.Empty : (String)dr[1];
//this is the part that i need to know how is it usually handled
//StudentDTO.StudentDetails = how to fill out this part ???
StudentCollection.Add(StudentDTO);
}
return StudentCollection;
}
}
catch (Exception)
{
return null;
}
}
}
编辑:
存储过程代码
select s.StudentID,s.StudentName,sd.StudentDetailsID,sd.Address,
sd.Height,sd.Weight
from Student s,StudentDetails sd
where s.StudentID = sd.StudentID
你有两个选择
1:一个单独的 sproc(或 sql)通过学生 ID 从学生详细信息 table 获取信息。每个学生都这样称呼
2:在您的 sproc/sql 中加入学生详细信息 table 并使用同一行数据填充两者
选项 1:通常更清洁且更可重用。我会说这应该是您的第一种方法。
但是,如果您需要检索很多学生,选项 2 会快得多。因为它只需要调用一次数据库。
而且你似乎在学生和学生细节之间有一对一的关系,所以没有理由不使用选项 2。但是如果你有一个学生的很多细节,你仍然可以使用选项 2,跳过重复的学生信息。这通常是最好的方法,即使您返回的数据多于 sql
所需的数据考虑到存储过程查询,您可以简单地:
StudentDTO.StudentDetails = new StudentDetails
{
StudentDetailsID = dr[2] == DBNull.Value ? 0 : (int)dr[2],
Address = dr[3] == DBNull.Value ? String.Empty : (String)dr[3],
...
};
您可以创建单独的函数来获取学生和学生详细信息记录。 这样您就可以在代码中的任何地方重复使用这些函数。
例如对于 student
你可以有这样的函数
public Student CreateStudent(IDataRecord iDataRecord)
{
Student stud = new Student();
stud.Id = GetValue<int>(iDataRecord, "Id");
stud.Name = GetValue<string>(iDataRecord, "Name");
return stud;
}
对于 studentDetails
,创建如下函数:
public StudentDetails CreateStudentDetails(IDataRecord iDataRecord)
{
StudentDetails studDetails = new StudentDetails();
studDetails.Id = GetValue<int>(iDataRecord, "Id");
studDetails.Address = GetValue<string>(iDataRecord, "Address");
studDetails.Height = GetValue<string>(iDataRecord, "Height");
studDetails.Weight = GetValue<string>(iDataRecord, "Weight");
return studDetails;
}
然后,在您的 FillStudent
方法中,只需调用:
Student student=this.CreateStudent(dr);
student.StudentDetails=this.CreateStudentDetails(dr);
请注意,此代码仅用于说明目的。您可以进一步重构此代码以将其单独放置以创建工厂 类。