Tôi thực sự không thấy thử thách là gì. Định nghĩa EmployeeDepartmentVM
ngụ ý rằng bạn cần nhóm nhóm kết quả theo số Department
. Giả sử tập kết quả là không có thứ tự, nó có thể đạt được bằng cách đơn giản duy trì một từ điển để định vị các mô hình khung nhìn của các bộ phận đã được thêm vào trong khi đọc.
nào dẫn đến một cái gì đó như thế này:
static List<EmployeeDepartmentVM> GetEmployeeDepartmentVMList(DbCommand command)
{
var resultById = new Dictionary<int, EmployeeDepartmentVM>();
using (var reader = command.ExecuteReader())
{
var employeeIdCol = reader.GetOrdinal("Id");
var employeeNameCol = reader.GetOrdinal("Name");
var departmentIdCol = reader.GetOrdinal("DId");
var departmentNameCol = reader.GetOrdinal("DName");
while (reader.Read())
{
var departmentId = reader.GetInt32(departmentIdCol);
EmployeeDepartmentVM result;
if (!resultById.TryGetValue(departmentId, out result))
{
result = new EmployeeDepartmentVM
{
department = new Department(),
employees = new List<Employee>()
};
result.department.Id = departmentId;
result.department.Name = reader.GetString(departmentNameCol);
resultById.Add(departmentId, result);
}
var employee = new Employee();
employee.Id = reader.GetInt32(employeeIdCol);
employee.Name = reader.GetString(employeeNameCol);
employee.DepartmentId = departmentId;
result.employees.Add(employee);
}
}
return resultById.Values.ToList();
}
Một số điều cần lưu ý. Cách viết, truy vấn SQL của bạn ngụ ý rằng các trường liên quan đến Bộ có thể là null (LEFT OUTER JOIN
). Tuy nhiên, mệnh đề WHERE
và mô hình Nhân viên (trường DepartmentId
không thể vô hiệu) ngụ ý rằng nó không thể xảy ra. Nếu mục đích là để bao gồm các phòng ban không có nhân viên, sau đó tốt hơn thay đổi tham gia để RIGHT OUTER
và sử dụng một cái gì đó như thế này:
// ...
if (reader.IsDBNull(employeeIdCol)) continue;
var employee = new Employee();
// ...
EDIT: Để hoàn chỉnh, đây là cách tiếp cận khác. Nó tương tự như cách EF materializes truy vấn tương tự và không cần từ điển tạm thời, nhưng đòi hỏi đầu vào thiết lập để được sắp xếp theo PK của bảng tổng thể, vì vậy bạn cần phải thêm
ORDER BY D.Id
ở phần cuối của SQL của bạn . Cơ sở dữ liệu có thể dễ dàng và hiệu quả cung cấp thứ tự như vậy, và lợi ích của giải pháp này là nó cho phép thực hiện hoãn lại và không yêu cầu xử lý toàn bộ thiết lập để bắt đầu trả về kết quả. Nó không cần thiết nếu bạn muốn chỉ nhận được một danh sách, nhưng có thể hữu ích trong các tình huống khác.
static IEnumerable<EmployeeDepartmentVM> GetEmployeeDepartmentVMs(DbCommand command)
{
using (var reader = command.ExecuteReader())
{
var employeeIdCol = reader.GetOrdinal("Id");
var employeeNameCol = reader.GetOrdinal("Name");
var departmentIdCol = reader.GetOrdinal("DId");
var departmentNameCol = reader.GetOrdinal("DName");
for (bool more = reader.Read(); more;)
{
var result = new EmployeeDepartmentVM
{
department = new Department(),
employees = new List<Employee>()
};
result.department.Id = reader.GetInt32(departmentIdCol);
result.department.Name = reader.GetString(departmentNameCol);
do
{
if (reader.IsDBNull(employeeIdCol)) continue;
var employee = new Employee();
employee.Id = reader.GetInt32(employeeIdCol);
employee.Name = reader.GetString(employeeNameCol);
employee.DepartmentId = result.department.Id;
result.employees.Add(employee);
}
while ((more = reader.Read()) && reader.GetInt32(departmentIdCol) == result.department.Id);
Debug.Assert(!more || reader.GetInt32(departmentIdCol) > result.department.Id); // Sanity check
yield return result;
}
}
}
Để có danh sách như cách tiếp cận đầu tiên, chỉ cần thêm ToList()
sau cuộc gọi, ví dụ:
var result = GetEmployeeDepartmentVMs(command).ToList();
Bạn có thể sử dụng phản chiếu để điền thuộc tính. http://stackoverflow.com/questions/1089123/setting-a-property-by-reflection-with-a-string-value –
Khi LEFT JOIN, đặt các điều kiện của bảng bên phải trong mệnh đề ON để thực hiện đúng hành vi kết nối trái . (Khi trong WHERE bạn nhận được kết quả bên trong thường xuyên tham gia.) I.e làm '... ON E.DepartmentId = D.Id AND D.Id = 1'. – jarlh
Tại sao bạn không thích sử dụng EF ..? Bạn phải viết nhiều mã hơn, nếu bạn không sử dụng ORM này .. – Karthick