2008-10-07 9 views
23

मुझे एक बिटमैस्क के साथ एक उपयोगकर्ता तालिका मिली है जिसमें उपयोगकर्ता की भूमिकाएं हैं। नीचे LINQ क्वेरी सभी उपयोगकर्ताओं की भूमिकाओं को शामिल 1, 4 या 16.आप एक linq क्वेरी में गतिशील 'कहां' खंड कैसे जोड़ते हैं?

var users = from u in dc.Users 
      where ((u.UserRolesBitmask & 1) == 1) 
       || ((u.UserRolesBitmask & 4) == 4) 
       || ((u.UserRolesBitmask & 16) == 16) 
      select u; 

मैं रिटर्न दिया भूमिकाओं से सभी उपयोगकर्ताओं इसलिए मैंने इसे पुनः उपयोग कर सकते करने के लिए नीचे दी गई विधि में इस पुनर्लेखन करना चाहते हैं देता है:

private List<User> GetUsersFromRoles(uint[] UserRoles) {} 

किसी भी संकेतक गतिशील रूप से मेरी क्वेरी कैसे बनाएं? धन्यवाद

उत्तर

31

आप PredicateBuilder कक्षा का उपयोग कर सकते हैं।

PredicateBuilder LINQKit NuGet package

LINQKit में जारी की गई है एसक्यूएल और इकाई की रूपरेखा बिजली उपयोगकर्ताओं के लिए LINQ के लिए एक्सटेंशन के एक मुक्त सेट है।

+3

उपयुक्त रूप से प्रिडिकेटबिल्डर वर्ग दो संस्करणों में उपलब्ध है: वेबसाइट पर स्रोत कोड उदाहरण, जो © अल्बाहारी और ओ'रेली है, सभी अधिकार सुरक्षित हैं; और लिंककिट के हिस्से के रूप में, जो "एक अनुमोदित मुक्त लाइसेंस के तहत है, जिसका अर्थ है कि आप इसे संशोधित कर सकते हैं, और इसे अपने वाणिज्यिक या गैर-वाणिज्यिक सॉफ्टवेयर में शामिल करें।" – Sjoerd

+0

लिंककिट NuGet के माध्यम से उपलब्ध है। –

2

मान लें कि आपके उपयोगकर्ता रोल मूल्य स्वयं बिटमैस्क हैं, क्या इस काम की तरह कुछ होगा?

private List<User> GetUsersFromRoles(uint[] UserRoles) { 
    uint roleMask = 0; 
    for (var i = 0; i < UserRoles.Length;i++) roleMask= roleMask| UserRoles[i]; 
    // roleMasknow contains the OR'ed bitfields of the roles we're looking for 

    return (from u in dc.Users where (u.UserRolesBitmask & roleMask) > 0) select u); 
} 

शायद एक अच्छा LINQ वाक्यविन्यास कि छोरों के स्थान पर काम करेंगे, लेकिन अवधारणा ही होना चाहिए।

+0

यह काम करना चाहिए। गतिशील के बजाय जहां खंड आपने इसे एक ही कम कर दिया। और आपके द्वारा वर्णित यह अच्छा LINQ वाक्यविन्यास हो सकता है: uint roleMask = UserRoles.Aggregate (0, (संयुक्त, भूमिका) => संयुक्त | भूमिका); – Lucas

1

यह कैसे है? यह गतिशील linq नहीं है, लेकिन लक्ष्य पूरा करता है।

private List<User> GetUsersFromRoles(uint[] userRoles) 
{ 
    List<User> users = new List<User>(); 

    foreach(uint userRole in UserRoles) 
    { 
     List<User> usersInRole = GetUsersFromRole(userRole); 
     foreach(User user in usersInRole) 
     { 
      users.Add(user); 
     } 
    } 
    return users; 
}  

private List<User> GetUsersFromRole(uint userRole) 
{ 
    var users = from u in dc.Users 
      where ((u.UserRolesBitmask & UserRole) == UserRole) 
      select u; 

    return users;  
} 
+0

उपयोगकर्ता।AddRange (usersInRole); –

+0

इसके अलावा, आपको GetUsersFromRole –

0
private List<User> GetUsersFromRoles(uint UserRoles) { 
    return from u in dc.Users    
     where (u.UserRolesBitmask & UserRoles) != 0 
     select u; 
} 

UserRoles पैरामीटर हालांकि, इसके बजाय थोड़ा सा मुखौटा के रूप में प्रदान किया जाना चाहिए सरणी।

+0

में ToList की आवश्यकता है, यह उन सभी उपयोगकर्ताओं को वापस कर देगा जो सभी दिए गए भूमिकाओं से मेल खाते हैं। उनकी विधि उन उपयोगकर्ताओं को लौटाती है जो किसी भी भूमिका निभाते हैं। – Lucas

3

यहाँ के परिवर्तनशील जोड़ने का एक तरीका है, जहां आपके LINQ क्वेरी के लिए खंड। ध्यान दें कि मैंने आपके बिटमैस्क तर्क को स्पर्श नहीं किया है, मैंने बस एकाधिक पर ध्यान केंद्रित किया है जहां एस है।

// C# 
private List<User> GetUsersFromRoles(uint[] UserRoles) 
{ 
    var users = dc.Users; 

    foreach(uint role in UserRoles) 
    { 
     users = users.Where(u => (u.UserRolesBitmask & role) == role); 
    } 

    return users.ToList(); 
} 

संपादित करें: वास्तव में, यह होगा औरजहां खंड और आप या उन्हें करना चाहता था। निम्नलिखित दृष्टिकोण (एक आंतरिक शामिल) LINQ से ऑब्जेक्ट्स में काम करता है लेकिन LINQ से SQL:

var result = from u in Users 
      from role in UserRoles 
      where (u.UserRolesBitmask & role) == role) 
      select u;