كيف يمكنك إضافة عبارات "حيث" الديناميكية إلى استعلام linq؟
سؤال
لدي جدول مستخدم بقناع نقطي يحتوي على أدوار المستخدم.يقوم استعلام linq أدناه بإرجاع جميع المستخدمين الذين تتضمن أدوارهم 1 أو 4 أو 16.
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) {}
هل هناك أي مؤشرات حول كيفية إنشاء استعلامي ديناميكيًا؟شكرًا
المحلول
ويمكنك استخدام PredicateBuilder الصف.
لقد تم الافراجوPredicateBuilder في LINQKit NuGet حزمة
<اقتباس فقرة>وLINQKit هو مجموعة خالية من ملحقات لLINQ إلى SQL ومستخدمي السلطة إطار الكيان.
اقتباس فقرة>نصائح أخرى
وعلى افتراض UserRoles الخاص القيم هي نفسها bitmasks، فإن شيئا مثل هذا العمل؟
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 لطيفة التي سوف تعمل في مكان الحلقات، ولكن هذا المفهوم يجب أن تكون هي نفسها.
وهناك عدة طرق يمكنك القيام بذلك:
والمكتبات استعلام LINQ الحيوي: <وأ href = "http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx" يختلط = " noreferrer نوفولو "> http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
والتعبير الأشجار وLAMDA تعبيرات: http://msdn.microsoft.com/en-us/library/bb882637. ASPX
إليك طريقة واحدة لإضافة عدد متغير من أين عبارات لاستعلام 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 إلى الكائنات ولكن لا يمكن ترجمته إلى SQL باستخدام LINQ إلى SQL:
var result = from user in Users
from role in UserRoles
where (user.UserRolesBitmask & role) == role
select user;
وكيف هذا؟ وليس من 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;
}
private List<User> GetUsersFromRoles(uint UserRoles) {
return from u in dc.Users
where (u.UserRolesBitmask & UserRoles) != 0
select u;
}
وUserRoles ينبغي توفير معلمة، ومع ذلك، كقناع بعض الشيء، بدلا من مجموعة.