2012-12-19 24 views
6

मेरी कंपनी में 0 से एन विभाग, 1 विभाग में 0 से एन कार्यालय, और 1 कार्यालय में 0 से एन एम्प्लीज़ हैं.अब मुझे एएमपीआई की औसत आयु सूचीबद्ध करने के लिए linq का उपयोग करके एक क्वेरी की आवश्यकता है विभाग, अगर एक विभाग में कोई भी नहीं तो डिफ़ॉल्ट औसत 0. कोड है नीचे है:बाहरी से LINQ से इकाइयों का उपयोग करके क्वेरी में शामिल हों

DataContext ctx = new DataContext(); 

    var q0 = from d in ctx.Departments 
      join o in ctx.Offices on d.Id equals o.DepartmentId 
      join e in ctx.Employees on o.Id equals e.OfficeId 
      group e by d into de 
      select new { 
       DepartmentId = de.Key.Id, 
       AverageAge = de.Count() == 0 ? 0 : de.Average(e => e.Age), 
      }; 


    var q1 = from d in ctx.Departments 
      join de in q0 on d.Id equals de.DepartmentId into des 
      from de in des.DefaultIfEmpty() 
      select new 
      { 
       DepartmentName = d.Name, 
       AverageAge = de == null ? 0 : de.AverageAge 
      }; 

    var result = q1.ToList(); 
    foreach (var item in result) 
    { 
     Console.WriteLine("{0}-{1}", item.DepartmentName, item.AverageAge); 
    } 
    ctx.Dispose(); 

लेकिन यह कैसे एक प्रश्न के Q0 और Q1 गठबंधन करने के लिए?

var newQ2 = from d in ctx.Departments 
        join o in ctx.Offices on d.Id equals o.DepartmentId 
        join e in ctx.Employees on o.Id equals e.OfficeId 
        group e by d into de.DefaultIfEmpty() 
        select new { 
         DepartmentId = de.Key.Id, 
         DepartdentName = select d.Name from d where d.id = de.Key.Id, 
         AverageAge = de.Count() == 0 ? 0 : de.Average(e => e.Age), 
        }; 

परिशिष्ट::

+2

यहाँ है: http://www.codeproject.com/Articles/488643/LinQ-Extended-Joins –

+0

बिल्कुल सही विस्तार। लेकिन वे विधियां हैं, धाराप्रवाह linq नहीं। – user1729842

उत्तर

7
were you meaning something along the lines of: 

var newQ2 = from d in ctx.Departments 
       outer left join o in ctx.Offices on d.Id equals o.DepartmentId 
       outer left join e in ctx.Employees on o.Id equals e.OfficeId 
       group e by d into de 
       select new { 
        DepartmentId = de.Key.Id, 
        AverageAge = de.Count() == 0 ? 0 : de.Average(e => e.Age), 
       }; 

करने के लिए बदल रहा अतिरिक्त नाम से मेल करने के लिए, अपने डाटाबेस लेआउट मैं अपने कोड से तात्कालिक है जानते हुए भी नहीं एक उप चयन का प्रयोग करेंगे, लेकिन आप यह अधिक कुशल बना सकता है और उप-चयनों के आधार पर एक मल्टीपार्ट भी शामिल हो सकता है। खेद है कि मैं काम पर इस कोड का परीक्षण नहीं कर सकता, मैं काफी अच्छी तरह से अनुमान लगा सकता हूं, लेकिन अगर आपको अधिक विस्तृत उत्तर की आवश्यकता है तो आपके विभाग के नाम कहां स्थित हैं, इस बारे में कुछ और जानकारी चाहिए :) मैंने बाहरी बाएं को वापस शामिल करने के लिए शामिल किया है, क्षमा करें मैं linq के साथ C# में भूल गया था आप कोड में बाहरी बाएं शामिल व्यवहार का कारण बनने के लिए DefaultIfEmpty() का उपयोग कर सकते हैं।

एक बाहरी बाएं जुड़ने से नल वापस आ जाएंगे जहां कोई संबंधित मूल्य नहीं है, लेकिन किसी भी हिस्से पर रिटर्न की अनुमति होगी जो संबंधित मूल्य रखती है। हालांकि शामिल हों, किसी भी नल प्रविष्टियों को वापस नहीं लौटाएगा, जो मुझे संदेह है कि आपके पास दो प्रश्न क्यों हैं?

मैंने जो प्रश्न प्रस्तुत किया है, उस पर एकमात्र चेतावनी यह है कि यदि आप शून्य हैं तो उन्हें उपयोग करने से पहले आपको आवश्यक मूल्यों को भरने की आवश्यकता होगी, उदाहरण के लिए विभाग आईडी को डीई शून्य होने पर इसे पॉप्युलेट करने के लिए कुछ तर्क की आवश्यकता होगी।

+0

मुझे लगता है कि आप नाम भाग में खींचने के लिए इसे थोड़ा और संशोधित कर सकते हैं और फिर मेरा मानना ​​है कि ओपीएस दूसरी क्वेरी अनावश्यक है। – pstrjds

+2

बाहरी बाएं जॉइन एक अच्छा समाधान है। लेकिन यह वैध लिनक्स सिंटैक्स नहीं है, अगर वाक्यविन्यास वैध है, तो 3 शब्द नीले रंग के रूप में नीले होंगे। – user1729842

0

आप सभी को धन्यवाद, मैं इस सवाल का जवाब मिल गया है:

निर्माण के बारे में एक अच्छा लेख LINQ के साथ जुड़ जाता
 var q1 = 
       from d in ctx.Departments 
       from o in ctx.Offices.Where(o => o.DepartmentId == d.Id).DefaultIfEmpty() 
       from e in ctx.Employees.Where(e => e.OfficeId == o.Id).DefaultIfEmpty() 
       group e by d into de 
       select new { 
        DepartmentName = de.Key.Name, 
        AverageAge = de.Average(e => e == null ? 0 : e.Age), 
       };