2010-11-08 4 views
1

Je récupère des données avec linq depuis sproc et j'obtiens une exception "La sous-requête a renvoyé plus de 1. Ceci n'est pas autorisé lorsque la sous-requête suit =,! =, <, < =,>,> = ou lorsque la sous-requête est utilisée comme expression. ". Chose étrange, c'est qu'il fonctionne bien à partir de SQL Server Management Studio. Le sproc est la suivante:Linq to sql retourne "La sous-requête a renvoyé plus de 1 valeur" mais ne devrait pas

BEGIN 
DECLARE @LoginRights Table(RowNo int, TabID int, MenuID int, ControlID int) 
INSERT INTO @LoginRights SELECT row_number() Over (order by ControlID), TabID, MenuID, ControlID FROM dbo.func_Action_LoginRoles(@LoginID) --WHERE [email protected] AND ControlID is not null 
DECLARE @RightsCount [email protected]@RowCount, @iRow int =1,@ControlID int,@MenuID int; 

DECLARE @Menu Table(MenuID int) 
INSERT INTO @Menu(MenuID) 
SELECT MenuID FROM (
SELECT m.ID MenuID, t.ID TabID FROM dbo.tblAction_Menu m JOIN dbo.tblAction_MenuGroup mg on m.GroupID=mg.ID JOIN tblAction_Tabs t on t.ID=mg.TabID 
WHERE t.ID IN(SELECT TabID FROM @LoginRights WHERE MenuID is null) or 
m.ID IN(SELECT MenuID FROM @LoginRights WHERE MenuID is not null) 
) m Group by m.MenuID 
DECLARE @ControlsInMenu Table(MenuID int, ControlID int) 
WHILE @iRow<[email protected] BEGIN 
SELECT @ControlID=ControlID, @MenuID=MenuID FROM @LoginRights WHERE [email protected] 
IF @MenuID is null BEGIN 
    INSERT INTO @ControlsInMenu(MenuID, ControlID) 
    SELECT MenuID, @ControlID FROM @Menu 
END ELSE BEGIN 
    INSERT INTO @ControlsInMenu(MenuID, ControlID) 
    SELECT @MenuID, @ControlID 
END 
SET @[email protected]+1 END 
SELECT MenuID, ControlID FROM @ControlsInMenu 
END 
 
The function: 
ALTER FUNCTION [dbo].[func_Action_LoginRoles] 
(@LoginID int) 
RETURNS @LoginsRoles TABLE(ID int, Name nvarchar(50), TabID int, MenuID int, ControlID int) 
AS 
BEGIN 
INSERT INTO @LoginsRoles (ID, Name, TabID, MenuID, ControlID) 
SELECT lr.ID, lr.Name, TabID, MenuID, ControlID FROM tblLogins_Roles lr 
    JOIN tblLogins_RolesInGroup rig ON lr.ID=rig.RolesID 
    JOIN tblLogins_Roles_Groups lrg ON lrg.ID=rig.Roles_GroupID 
    JOIN tblLogins l ON l.Roles_GroupID=lrg.ID WHERE [email protected] 
RETURN 
END 

méthode de récupération de données est ce (C#/LINQ to SQL):

var ControlsInMenu = from c in dc.proc_Action_ControlsInMenu(LoginData.LoginID, TabID) 
        select new 
        { 
         c.MenuID, 
         c.ControlID 
        }; 
+0

Définir "exécute OK SQL server Management studio". Il renvoie précisément 1 ligne dans SSMS? –

+1

Je ne peux même pas * voir * une sous-requête suivant =,! = Etc - êtes-vous sûr que le problème ne se trouve pas dans 'func_Action_LoginRoles'? –

+0

S'il vous plaît pouvez-vous poster 'func_Action_LoginRoles' - sinon je vais conclure qu'il n'y a pas assez d'informations pour répondre à cette question ... –

Répondre

1

Ah. Votre requête retourne plusieurs ensembles de résultats (un par temps dans la boucle), et LINQ to SQL est probablement incapable de traiter cela.

Si vous voulez LINQ to SQL pour traiter, je vous suggère échanger les deux lignes suivantes:

SELECT MenuID, ControlID FROM @ControlsInMenu 
END 
+0

Merci. Mais ce n'est pas le cas je pense. Si je supprime tout le code et ne laisse qu'une seule sélection de l'instruction table, linq se bloque tout de même (sproc ne le fait pas). Je reçois probablement des données directement à partir de la table (var MenuGroup = de m dans dc.tblAction_MenuGroups) bien que cela soit juste intéressant pourquoi linq s'est effondré. – Saulius

0

vérifier pour voir si vous obtenez des doublons de dbo.func_Action_LoginRoles (@LoginID)

0

J'ai trouvé. Erreur "Sous-requête retourné plus de 1 valeur .." s'est produite pas dans la procédure où il a été montré dans le db.designer. Il s'est effectivement produit dans la méthode de consommation de données précédente. Principe KISS célèbre en action :-)