2016-05-13 7 views
10

मैं दो तालिकाओं है:कैसे सी # मॉडल को SQL ऑब्जेक्ट से डेटा कॉपी करने के लिए संपत्ति

  • कर्मचारी: Id, Name, DepartmentId
  • विभाग: Id, Name

Employee.cs:

public int Id {get;set;} 
public string Name {get;set;} 
public int DepartmentId {get;set;} 

Department.cs:

public int Id {get;set;} 
public string Name {get;set;} 

ViewModel: EmployeeDepartmentVM:

public Department department {get;set;} 
public List<Employee> employees {get;set;} 

इन दो तालिकाओं मैं इस कोड लिखा है में शामिल होने के लिए:

SELECT E.* , D.Id as DId , D.Name as DName 
    from [Employee] as E 
    LEFT OUTER JOIN [Department] as D 
    ON E.DepartmentId = D.Id 
    where D.Id = 1 

मैं कैसे ऊपर से EmployeeDepartmentVM प्रकार मिलता है क्वेरी?

मैं जानता हूँ कि अगर मैं अपने समस्या की तरह एक मॉडल बारे में हल किया जाएगा:

public int Id {get;set;} 
public string Name {get;set;} 
public int DepartmentId {get;set;} 
public int DId {get;set;} 
public string Name {get;set;} 

लेकिन मैं अतिरिक्त मॉडल लिखने के लिए नहीं करना चाहती। बस क्वेरी डेटा को EmployeeDepartmentVM प्रकार में बाध्य करना चाहते हैं।

+1

आप गुणों को भरने के लिए प्रतिबिंब का उपयोग कर सकते हैं। http://stackoverflow.com/questions/1089123/setting-a-property-by-reflection-with-a-string-value –

+1

जब बाएं जॉइन हों, तो दाईं ओर तालिका में दाएं तरफ तालिका की स्थितियों को सही बाएं व्यवहार में डाल दें । (जब आप नियमित रूप से आंतरिक परिणाम प्राप्त करते हैं।) मैं करता हूं ... ... ई। डिपार्टमेंट आईडी = डी.आईडी और डी.आईडी = 1'। – jarlh

+1

आप ईएफ का उपयोग क्यों नहीं करना चाहते हैं ..? यदि आप इस ओआरएम का उपयोग नहीं कर रहे हैं, तो आपको अधिक कोड लिखना होगा .. – Karthick

उत्तर

7

मैं वास्तव में नहीं देखता कि चुनौती क्या है। EmployeeDepartmentVM परिभाषा का तात्पर्य है कि आपको परिणाम सेट को Department द्वारा समूहित करने की आवश्यकता है। परिणाम सेट मानना ​​अनियंत्रित है, इसे पढ़ने के दौरान पहले से जोड़े गए विभागों के दृश्य मॉडल का पता लगाने के लिए केवल एक शब्दकोश को बनाए रखने के द्वारा हासिल किया जा सकता है।

कौन सा कुछ इस तरह की ओर जाता है:

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(); 
} 

कुछ बातों का ध्यान रखना। जिस तरह लिखा गया है, आपकी एसक्यूएल क्वेरी का तात्पर्य है कि विभाग से संबंधित क्षेत्र शून्य हो सकते हैं (LEFT OUTER JOIN)। हालांकि, WHERE खंड और कर्मचारी मॉडल (DepartmentId फ़ील्ड गैर शून्य नहीं) का तात्पर्य है कि ऐसा नहीं हो सकता है। आशय नहीं कर्मचारियों के साथ विभागों को शामिल करने के है, तो बेहतर इस तरह RIGHT OUTER करने में शामिल होने और कुछ का उपयोग बदलने के लिए:

// ... 
if (reader.IsDBNull(employeeIdCol)) continue; 
var employee = new Employee(); 
// ... 

संपादित करें: पूर्णता के लिए, यहाँ एक और तरीका है। यह रास्ता एफई मिलती-जुलती क्वेरी materializes और अस्थायी शब्दकोश की जरूरत नहीं है के समान है, लेकिन इनपुट मास्टर तालिका के पी द्वारा आदेश दिया जा करने के लिए सेट की आवश्यकता है, तो आप अपने एसक्यूएल के अंत में

ORDER BY D.Id 

जोड़ने की जरूरत । डेटाबेस आसानी से और कुशलतापूर्वक ऐसे आदेश प्रदान कर सकते हैं, और इस समाधान का लाभ यह है कि यह स्थगित निष्पादन की अनुमति देता है और परिणामों को वापस करने के लिए पूरे सेट को संसाधित करने की आवश्यकता नहीं होती है। यदि आप केवल एक सूची प्राप्त करना चाहते हैं, तो यह आवश्यक नहीं है, लेकिन अन्य परिदृश्यों में उपयोगी हो सकता है।

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; 
     } 
    } 
} 

पहले दृष्टिकोण में के रूप में एक सूची प्राप्त करने के लिए, बस कॉल करता है, उदा के बाद ToList() जोड़ने

var result = GetEmployeeDepartmentVMs(command).ToList(); 
+0

या। इससे मेरा काम बनता है। एक सवाल। क्या मैं शब्दकोश के बजाय सूची का उपयोग कर सकता हूं? –

+1

आप कर सकते हैं, लेकिन यदि आप विभाग फ़िल्टर लागू नहीं करते हैं तो यह अक्षम होगा। समूहीकरण कार्यान्वयन आमतौर पर किसी प्रकार की हैश डेटा संरचना (जैसे शब्दकोश) या क्रमबद्ध परिणाम सेट (जैसे ईएफ) का उपयोग करते हैं। शब्दकोश केवल अस्थायी है, जैसा कि आप देख सकते हैं, मैं इसे अंत में सूची में परिवर्तित कर रहा हूं। –

संबंधित मुद्दे

 संबंधित मुद्दे