Pourquoi le cadre Entity ne peut-il pas voir les informations de la colonne de ma procédure stockée?
j'ai la procédure stockée suivante et quand je tente de fonction Importer il dit que ma procédure stockée ne retourne aucune colonne. Ce qui me manque? Toutes Les Suggestions?
Le Proc:
ALTER PROCEDURE [healthc].[ev_kc_Products_Search]
(
@SearchString VARCHAR(1000)
)
AS
SET NOCOUNT ON
DECLARE @SQL VARCHAR(max),
@SQL1 VARCHAR(max),
@Tag VARCHAR(5)
CREATE TABLE #T
( ID INT,
VendorName VARCHAR(255),
ItemName VARCHAR(255),
Type VARCHAR(2),
Sequence TINYINT
)
SET @SQL = '
INSERT #T
SELECT VendorID ID,
Name VendorName,
NULL ItemName,
''V'' Type,
0 Sequence
FROM tblVendors
WHERE '+REPLACE(@SQL1,@Tag,'Name')+'
UNION ALL
BLAH BLAH BLAH'
EXEC(@SQL)
SELECT ID, VendorName, ItemName, Type FROM #T
9 réponses
Essayez d'ajouter cette ligne au début de votre procédure stockée:
SET FMTONLY OFF
vous pouvez supprimer cela après que vous avez terminé l'importation.
que se passe-t-il dans les coulisses?
-
" tout en faisant l'importation de fonction -> Obtenir des informations de colonne ... Visual Studio exécute le proc stocké avec toutes les valeurs param comme NULL (vous pouvez le vérifier par le profileur MS SQL).
-
en faisant l'étape 1, les colonnes résultantes de proc stockées sont retournées avec son type de données et des informations de longueur.
-
une fois la colonne info est récupérée, en cliquant sur le bouton' Create New Complex Type ' qui crée le type complexe de la SP dans contention.
dans votre cas, les paramètres proc stockés ne sont pas nulles, donc L'appel de Visual Studio échoue et ne renvoie aucune colonne.
Comment gérer cela?
IF (1=0) BEGIN SET FMTONLY OFF if @param1 is null and @param2 is null then begin select cast(null as varchar(10)) as Column1, cast(null as bit) as Column2, cast(null as decimal) as Column3 END END
Pour être précis (dans votre cas):
IF (1=0) BEGIN SET FMTONLY OFF if @SearchString is null then BEGIN select cast(null as int) as ID, cast(null as varchar(255)) as VendorName, cast(null as varchar(255)) as ItemName, cast(null as varchar(2)) as Type END END
en complétude et en réponse simple à @benshabatnoam, mettez juste le code suivant au début :
IF (1=2)
SET FMTONLY OFF
Note: il fonctionne dans EF 6.1.3 et Visual Studio 2015 Mise À Jour 3
vous avez ce problème à cause de la température. Tout ce que vous devez faire est de: 1. Modifiez votre procédure stockée pour retourner le statemant select sans la table de température. 2. Allez à la fonction Importer et obtenez les informations de la colonne. 3. Modifiez votre procédure enregistrée de nouveau à l'original.
comme un moyen rapide et sale pour faire EF trouver les colonnes, commentez la clause où dans votre proc stocké (peut-être ajouter un TOP 1 pour l'empêcher de tout retourner), ajouter le proc à L'EF et créer le Type complexe, puis décommenter la clause où à nouveau.
si vous utilisez une table temporaire, L'entité (EDMX) ne peut pas comprendre ce qui se passe.
alors retournez le résultat vide avec le nom des colonnes, Commentez toutes vos procédures stockées et exécutez dans le gestionnaire sql, puis obtenez le type complexe dans visual studio. Après l'enregistrement, le retour de votre procédure stockée à son état d'origine (sans commentaire).
bonne chance /
J'aimerais ajouter quelque chose à la réponse de Sudhanshu Singh: cela fonctionne très bien, mais si vous avez des structures plus complexes, combinez-le avec une déclaration de table.
j'ai utilisé avec succès ce qui suit (placez-le au tout début de votre procédure enregistrée):
CREATE PROCEDURE [EY].[MyStoredProc]
AS
BEGIN
SET NOCOUNT ON;
IF (1=0)
BEGIN
SET FMTONLY OFF
BEGIN
-- declaration + dummy query
-- to allow EF obtain complex data type:
DECLARE @MyStoredProcResult TABLE(
ID INT,
VendorName VARCHAR(255),
ItemName VARCHAR(255),
Type VARCHAR(2),
Sequence TINYINT
);
SELECT * FROM @MyStoredProcResult WHERE (1=0)
END
END
-- your code follows here (SELECT ... FROM ...)
-- this code must return the same columns/data types
--
-- if you require a temp table / table variable like the one above
-- anyway, add the results during processing to @MyStoredProcResult
-- and then your last statement in the SP can be
-- SELECT * FROM @MyStoredProcResult
END
Note que le 1=0
garantit qu'il n'est jamais exécuté, mais le fe en déduit la structure.
Après avoir sauvegardé votre procédure stockée, ouvrez le fichier EDMX dans Visual Studio, rafraîchissez le modèle de données, allez dans le navigateur de modèle Entity Frameworks. Dans le navigateur de modèle, localisez votre procédure stockée, ouvrez la boîte de dialogue" Éditer la fonction Importer", sélectionnez " retourne une collection de ... Complexe", puis cliquez sur le bouton "Obtenir les Informations de Colonne".
il doit montrer la structure telle que définie ci-dessus. Si c'est le cas, cliquez sur "Créer un nouveau type complexe", et il en créera un avec le nom de la procédure stockée, par exemple" MyStoredProc_Result "(ajouté par"_Result").
Maintenant, vous pouvez le sélectionner dans le combobox De " renvoie une collection de ... Complexe" sur la même boîte de dialogue.
chaque fois que vous avez besoin de mettre à jour quelque chose, mettre à jour le SP d'abord, puis vous pouvez revenir à la fonction D'édition importer dialogue et cliquez sur le bouton "Mise à jour" (vous n'avez pas besoin de tout recréer à partir de zéro).
j'ai eu ce problème, ce que j'ai dû faire était de créer un type de Table défini par L'Utilisateur et de retourner cela.
CREATE TYPE T1 AS TABLE
( ID INT,
VendorName VARCHAR(255),
ItemName VARCHAR(255),
Type VARCHAR(2),
Sequence TINYINT
);
GO
votre procédure stockée ressemblera maintenant à ceci:
ALTER PROCEDURE [healthc].[ev_kc_Products_Search]
(
@SearchString VARCHAR(1000)
)
AS
SET NOCOUNT ON
DECLARE @SQL VARCHAR(max),
@SQL1 VARCHAR(max),
@Tag VARCHAR(5)
@T [schema].T1
SET @SQL = 'SELECT VendorID ID,
Name VendorName,
NULL ItemName,
''V'' Type,
0 Sequence
FROM tblVendors
WHERE '+REPLACE(@SQL1,@Tag,'Name')+'
UNION ALL
BLAH BLAH BLAH'
INSERT INTO @T
EXEC(@SQL)
SELECT ID, VendorName, ItemName, Type FROM @T
ajoutez simplement la déclaration select sans la citation, exécutez le proc stocké, allez mettre à jour le modèle, éditez votre fonction Importer et obtenir des informations de colonne. Cela devrait remplir les nouvelles colonnes. Mettre à jour le jeu de résultats et revenir à votre proc stocké et supprimer la liste de sélection que vous venez d'ajouter. Et exécutez le processeur stocké. De cette façon, vos colonnes seront peuplées dans le jeu de résultats. Voir ci-dessous où ajouter la liste select sans devis.
ALTER PROCEDURE [healthc].[ev_kc_Products_Search]
(
@SearchString VARCHAR(1000)
)
AS
SET NOCOUNT ON;
SELECT VendorID ID,
Name VendorName,
NULL ItemName,
''V'' Type,
0 Sequence
FROM tblVendors
DECLARE @SQL VARCHAR(max),
@SQL1 VARCHAR(max),
@Tag VARCHAR(5)
CREATE TABLE #T
( ID INT,
VendorName VARCHAR(255),
ItemName VARCHAR(255),
Type VARCHAR(2),
Sequence TINYINT
)
SET @SQL = '
INSERT #T
SELECT VendorID ID,
Name VendorName,
NULL ItemName,
''V'' Type,
0 Sequence
FROM tblVendors
WHERE '+REPLACE(@SQL1,@Tag,'Name')+'
UNION ALL
BLAH BLAH BLAH'
EXEC (@SQL)
sélectionnez ID, VendorName, ItemName, Type FROM #T
j'espère que cela aide quelqu'un là-bas.