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
28
demandé sur RodneyRoadRunner 2011-05-13 23:35:15

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.

46
répondu benshabatnoam 2013-11-12 07:11:20

que se passe-t-il dans les coulisses?

  1. " 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).

  2. 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.

  3. 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   

référence: http://mysoftwarenotes.wordpress.com/2011/11/04/entity-framework-4-%E2%80%93-the-selected-stored-procedure-returns-no-columns-part-2 /

33
répondu Sudhanshu Singh 2017-10-09 08:25:23

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

6
répondu Mahmoud Moravej 2016-11-14 06:03:54

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.

2
répondu benshabatnoam 2014-08-20 12:05:48

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.

1
répondu SteveCav 2013-06-13 23:46:24

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 /

1
répondu Ehud Grand 2015-09-06 10:35:14

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).

1
répondu Matt 2017-10-09 07:38:39

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
0
répondu Wesley Coetzee 2016-02-15 06:55:52

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.

0
répondu Yoky 2016-07-13 00:27:22