2010-04-19 11 views
5

मेरे IQueryable लाइन है:लिंक एक IQueryable <T> (System.Data.Linq.DataQuery) किसी सूची <T> (System.Collection.Generic.List) ऑब्जेक्ट द्वारा ऑब्जेक्ट फ़िल्टरिंग फ़िल्टरिंग?

// find all timesheets for this period - from db so System.Data.Linq.DataQuery 
var timesheets = _timesheetRepository.FindByPeriod(dte1, dte2); 

मेरी सूची लाइन है:

// get my team from AD - from active directory so System.Collection.Generic.List 
var adUsers = _adUserRepository.GetMyTeam(User.Identity.Name); 

मैं timesheet संग्रह में उन उपयोगकर्ताओं है कि उपयोगकर्ता संग्रह में मौजूद हैं के लिए केवल शो timesheets करना चाहते हैं।

अगर मैं इस तरह के रूप में एक मानक सी # अभिव्यक्ति का उपयोग:

var teamsheets = from t in timesheets 
        join user in adUsers on t.User1.username equals user.fullname 
        select t; 

मैं त्रुटि मिलती है "एक IQueryable कि एक स्वयं को संदर्भित लगातार अभिव्यक्ति देता है समर्थित नहीं है"

कोई सिफारिशों?

+0

टीमें कितनी बड़ी हैं? – SteadyEddi

+0

प्रति टीम 20 से अधिक उपयोगकर्ता यदि ऐसा नहीं है तो। – Klaptrap

उत्तर

3

जुड़ने का निर्माण काम नहीं करेगा, लेकिन आप Contains दृष्टिकोण का उपयोग कर सकते हैं। यह अगला स्निपेट चाल कर सकता है।

string[] usernames = adUsers.Select(u => u.fullname).ToArray(); 

var teamsheets = 
    from t in timesheets 
    where usernames.Contains(t.User1.username) 
    select t; 
+0

इसे क्रैक किया जाना चाहिए - धन्यवाद – Klaptrap

4

लिंक से एसक्यूएल पूरी अभिव्यक्ति का प्रतिनिधित्व करने के लिए एक एसक्यूएल क्वेरी उत्पन्न करने का प्रयास करेगा। इसका अर्थ यह है कि यह विज्ञापन उपयोगकर्ताओं के संग्रह में एसक्यूएल क्वेरी के पैरामीटर के रूप में पास करने का प्रयास करेगा। यदि बहुत से उपयोगकर्ता हैं तो क्वेरी पैरामीटर सीमा (2100) पर पहुंच जाएगी और इसे निष्पादित नहीं किया जा सकता है। यदि टीम में ऐसे कई उपयोगकर्ता नहीं हैं, तो आप एक अभिव्यक्ति अभिव्यक्ति का उपयोग कर सकते हैं जिसे SQL में "IN" अभिव्यक्ति में परिवर्तित किया जाएगा।

यह वही है स्टीवन सुझाव दिया गया है:

string[] usernames = adUsers.Select(u => u.fullname).ToArray(); 

var teamsheets = 
from t in timesheets 
where usernames.Contains(t.User1.username) 
select t; 

एक ही रास्ता (ToList का उपयोग करने पर स्मृति में एक तरीका है कि आप का प्रयास किया है में शामिल होने का उपयोग करने के होगा डेटाबेस से timesheets के सभी पुनः प्राप्त करने के टाइम्सशीट var), और फिर शामिल होने में स्मृति में होगा। यदि यह कंटेन का उपयोग करने से बेहतर प्रदर्शन करता है, या आप टीम के आकार के कारण उपयोग नहीं कर सकते हैं, तो यह विचार करने लायक हो सकता है।

+0

अतिरिक्त स्पष्टीकरण के लिए धन्यवाद - यह सब एक अलग प्रकाश में समझ में आता है। – Klaptrap

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