Как присоединиться к LinQ в наборе данных? - PullRequest
4 голосов
/ 02 апреля 2011

Я недавно обновил VS 2005 до 2010, и я довольно новичок в LinQ. Может быть, кто-то может поставить меня на правильный путь.

Фон : У меня есть типизированный набор данных, и стандартный SQLMembershipProvider расширен с помощью таблицы AccessRule. Таким образом, роль может иметь бесконечные AccessRules (например, «Администратор» имеет «DeleteCustomer»). Я использую пользовательский поставщик членства, который наследуется от SqlMemberShipProvider и имеет перегруженную функцию hasAccess (одна с набором данных памяти в качестве параметра, а другая использует базу данных напрямую).

Это полная модель:

enter image description here

Теперь мне нужно знать, например если пользователь с идентификатором пользователя = '89f9ea8d-8ae1-460b-a430-aa433261feec' имеет AccessRule «DeleteCustomer».

В SQL это будет примерно так:

SELECT     CASE WHEN aspnet_AccessRule.idAccessRule IS NULL THEN 0 ELSE 1 END AS Access
FROM         aspnet_RoleAccessRule INNER JOIN
                      aspnet_AccessRule ON aspnet_RoleAccessRule.fiAccessRule = aspnet_AccessRule.idAccessRule INNER JOIN
                      aspnet_Roles ON aspnet_RoleAccessRule.fiRole = aspnet_Roles.RoleId INNER JOIN
                      aspnet_UsersInRoles ON aspnet_Roles.RoleId = aspnet_UsersInRoles.RoleId
WHERE (aspnet_UsersInRoles.UserId = @UserID) AND    (aspnet_AccessRule.RuleName =@RuleName) 

Короче :

как мне получить от aspnet_UsersInRoles до aspnet_AccessRule с LinQ?

Заранее спасибо ...

Редактировать

Хотя C # также приветствуется, я предпочитаю VB.Net.

Это то, что у меня есть, но это не работает.

Dim query = From accRule In dsAuth.aspnet_AccessRule _
                        From roleAccRule In dsAuth.aspnet_RoleAccessRule _
                        From role In dsAuth.aspnet_Roles _
                        From userRole In dsAuth.aspnet_UsersInRoles _
                        Where roleAccRule.fiAccessRule = accRule.idAccessRule _
                        And roleAccRule.fiRole = role.RoleId _
                        And userRole.RoleId = role.RoleId _
                        And userRole.UserId = userID And accRule.RuleName = accessRule
            Select accRule.idAccessRule 
Return query.Any

Я получаю "Definition of method SelectMany is not accessible in this context" предупреждение компилятора и подсвечивается второе From. Я предполагаю, что это как-то связано с составными ключами в aspnet_RoleAccessRule и aspnet_UsersInRoles. Есть предложения?

Это дает то же исключение для первой запятой:

Dim query = From accRule In dsAuth.aspnet_AccessRule, _
           roleAccRule In dsAuth.aspnet_RoleAccessRule, _
           role In dsAuth.aspnet_Roles, _
           userRole In dsAuth.aspnet_UsersInRoles _
           Where accRule.idAccessRule = roleAccRule.fiAccessRule _
           And roleAccRule.fiRole = role.RoleId _
           And userRole.RoleId = role.RoleId _
           And userRole.UserId = userID And accRule.RuleName = accessRule
     Select accRule.idAccessRule
Return query.Any

Это синтаксис объединения, но с похожей ошибкой (Join не доступен в контексте ..):

Dim userID As Guid = DirectCast(Membership.GetUser.ProviderUserKey, Guid)
        Dim query = From accRule In dsAuth.aspnet_AccessRule _
                       Join roleAccRule In dsAuth.aspnet_RoleAccessRule _
                       On accRule.idAccessRule Equals roleAccRule.fiAccessRule _
                       Join role In dsAuth.aspnet_Roles _
                       On role.RoleId Equals roleAccRule.fiRole _
                       Join userRole In dsAuth.aspnet_UsersInRoles _
                       On userRole.RoleId Equals role.RoleId _
                       Where userRole.UserId = userID And accRule.RuleName = accessRule
                 Select accRule.idAccessRule
        Return query.Any

Решение : Я забыл импортировать пространство имен System.LinQ. Все эти запросы работают.

Примечание: Синтаксис соединения - самый быстрый запрос. Взгляните на мой вопрос: Почему LINQ JOIN намного быстрее, чем соединение с WHERE?

Ответы [ 2 ]

3 голосов
/ 02 апреля 2011

Боюсь, что кто-нибудь придет и начнет бросать в меня камни, но я рискну. Я бы наверное начал с этого:

var AccessRules = from ar in aspnet_AccessRule
            from rar in aspnet_Role
            from r in aspnet_Roles
            from uir in aspnet_UsersInRoles
            where ar.idaccessrule == rar.fiAccessRule
            where rar.fiRole == r.RoleId
            where r.RoleId == uir.RoleId
            select ar;

Хммм .. Я действительно не знаю, как выглядит ваш набор данных, но я думаю, что вы поняли смысл этого псевдокода.

Редактировать: вот ссылка на инструмент, который может вам помочь: Linqer

1 голос
/ 02 апреля 2011

Этот поток может помочь вам преобразовать ваш SQL в LINQ:

Каков синтаксис внутреннего соединения в LINQ to SQL?

...