25

Entity Frameworkを使用していて、テーブルとそのストアドプロシージャを更新しましたが、ストアドプロシージャを呼び出すと、次のエラーが発生します。

データリーダーは、指定された「FormValueModel.Valuation」と互換性がありません。タイプ'ValuationId'のメンバーには、同じ名前の対応する列がデータリーダーにありません。

ValuationIdは、自動インクリメントしたい主キーウィッチです。

SQL Management Studioからストアドプロシージャ検索を実行できます。アプリケーションを実行すると、データベースに書き込まれますが、エラーメッセージが表示されます。

私はEntityFrameworkに慣れておらず、基本的なことだけを知っています。これは、model.edmxからのマッピングの問題である可能性があります。

モデル内のテーブルとストアドプロシージャを再作成してマッピングする際の正しい手順は何でしょうか。


ストアドプロシージャ。

    ALTER PROCEDURE [dbo].[ValuationCreate]
    @TrackingNumber varchar(100),
    @FormMobiValuationId varchar(100),
    @ValuationPropertyId int,
    @ValuationFileName varchar(50)

AS   

SET NOCOUNT ON
SET XACT_ABORT ON


DECLARE @ErrorMessage varchar(1000)



BEGIN TRANSACTION


    --Insert to Valuation
    INSERT INTO [Valuation]
    (
        TrackingNumber,
        FormMobiValuationId,
        ValuationPropertyId, -- new
        ValuationFileName,
        Date,
        ValuationStatus,
        IsActive
    )
    VALUES
    (
        @TrackingNumber,
        @FormMobiValuationId,
        @ValuationPropertyId,--new
        @ValuationFileName,
        GETDATE(),
        1, --Created
        1
    )





IF @@ERROR > 0
BEGIN
    SET @ErrorMessage = 'Valuation Insert failed'
    GOTO ErrorHandler
END
ELSE
BEGIN
    COMMIT TRANSACTION
    RETURN
END



ErrorHandler:

RAISERROR(@ErrorMessage,16,1);
ROLLBACK TRANSACTION
RETURN -1

エラーが発生したC#呼び出し。エラーメッセージは最後の行に表示されます。

 public ObjectResult<Valuation> ValuationCreate(global::System.String trackingNumber, global::System.String formMobiValuationId, Nullable<global::System.Int32> valuationPropertyId, global::System.String valuationFileName)
        {
            ObjectParameter trackingNumberParameter;
            if (trackingNumber != null)
            {
                trackingNumberParameter = new ObjectParameter("TrackingNumber", trackingNumber);
            }
            else
            {
                trackingNumberParameter = new ObjectParameter("TrackingNumber", typeof(global::System.String));
            }

            ObjectParameter formMobiValuationIdParameter;
            if (formMobiValuationId != null)
            {
                formMobiValuationIdParameter = new ObjectParameter("FormMobiValuationId", formMobiValuationId);
            }
            else
            {
                formMobiValuationIdParameter = new ObjectParameter("FormMobiValuationId", typeof(global::System.String));
            }

            ObjectParameter valuationPropertyIdParameter;
            if (valuationPropertyId.HasValue)
            {
                valuationPropertyIdParameter = new ObjectParameter("ValuationPropertyId", valuationPropertyId);
            }
            else
            {
                valuationPropertyIdParameter = new ObjectParameter("ValuationPropertyId", typeof(global::System.Int32));
            }

            ObjectParameter valuationFileNameParameter;
            if (valuationFileName != null)
            {
                valuationFileNameParameter = new ObjectParameter("ValuationFileName", valuationFileName);
            }
            else
            {
                valuationFileNameParameter = new ObjectParameter("ValuationFileName", typeof(global::System.String));
            }

            return base.ExecuteFunction<Valuation>("ValuationCreate", trackingNumberParameter, formMobiValuationIdParameter, valuationPropertyIdParameter, valuationFileNameParameter);
        }
4

13 に答える 13

16

このメッセージは、ストアド プロシージャの結果に という名前の列が含まれていないことを意味しますValudationId。ステートメントを再確認selectし、SSMS で実行して、その列が戻っていることを確認します。

編集:プロシージャにはステートメントが含まれていませんselect。挿入された ID 値を (scope_identity()たとえば、関数を使用して) 選択して、EF がそれをエンティティにマップし直すことができるようにする必要があります。

例えば、

insert into Table
(
    Col1,
    Col2
)
values
(
    1,
    2
)

select scope_identity() as IdentityColName

また、余談ですが、insert ステートメントにすべてのトランザクション ビジネスが必要なわけではありません。データを変更するステートメント (挿入) は 1 つしかありません。

于 2013-01-09T13:02:24.737 に答える
10

私の場合、データを返していましたが、列名のエイリアスを持たないステートメントが原因で、列名が提供されず、空白になりました。欠落している列名のエラーにより、EF によって報告されたマッピングの失敗が生成されました。CAST

SSMS で実際の呼び出しを行い、結果を表示すると、その実際の結果は次の明らかな間違いを示しました。

ここに画像の説明を入力

SQL の列に EF が期待する名前を付けると、問題が修正されました。

于 2016-03-09T20:37:32.233 に答える
4

Avinash、ExecuteSQLCommand と「非クエリ」の適切な呼び出し。ただし、ポルノスターは ExecuteFunction を参照して SP を呼び出し、結果を返しています。この問題を解決するには、SP から「return」ステートメントを削除すると機能します。return ステートメントを使用すると、SP は select クエリではなく int を返します。

于 2014-05-19T04:34:31.770 に答える
2

挿入/削除/更新している場合 (これらは EF によって「非クエリ」と見なされます)、次を使用してコードから呼び出すことができます。

context.Database.ExecuteSqlCommand(insert into Table (Col1,Col2) values (1,2));

ただし、生の SQL ステートメントに対して選択クエリを実行している場合は、次を使用します。

context.DbSet<Table_name>.SqlQuery(select * from table_name).ToList();

または context.Database.SqlQuery(select * from table_name).ToList();

奇妙な理由により、EF の SqlQuery() 関数は、挿入/削除/更新操作で例外をスローします。(スローされる例外は、「型のメンバーであり、データ リーダーに同じ名前の対応する列がありません。」) しかし、Sql Management Studio を開いてエントリを確認すると、実際には操作が実行されています。

于 2013-10-11T07:10:05.110 に答える
2

奇妙なことに、ストアド プロシージャの最後にGOコマンドを追加することでこれを解決しました。

于 2015-01-15T16:34:50.673 に答える
2

VS でモデルを参照し、Function Imports で Stored Proc を見つけ、関数の戻り値の型を None に変更することで、この問題のバージョンを修正しました。

于 2015-02-27T17:44:07.037 に答える
1

重要なシナリオの 1 つは、異なる条件によって異なる結果を返すことです。たとえば、IF コマンドを使用すると、各ブランチから異なる結果セットが返される場合があります。EF は SP のインポート時に返されるコレクションを設定するため、[タイプ 1] コレクションを期待しますが、[タイプ 2] コレクションを取得するとエラーが発生し、データ リーダーに対応する列がありません。したがって、結果セットを返す SP は、そのすべての部分から同じコレクション (列名とカウントとして) を返す必要があります。以下のように:

IF (Condition 1)
BEGIN
  SELECT [column1], [column2], [column3], ... FROM [...]
END
ELSE
BEGIN
  SELECT [column1], [column2], [column3], ... FROM [...]
END

これは同じ問題で私のために働いており、役に立てば幸いです。

アップデート:

で間違った Return Collection Type を持っていたときに、このエラー メッセージが表示されましたFunction Imports。本当に Typed またはいくつかの Collection 値を期待していなかったので、Out パラメータとして整数が必要なだけかもしれませんが、に設定Returns a Collection Ofするのを忘れていましたNone。したがって、返される結果が期待できない場合は、モデルに移動し、Model Browser[ Function ImportsSP has issues] を右クリックして [編集] をクリックし、Returns a Collection Ofセクションを確認して に設定しNoneます。

于 2014-12-25T22:54:27.003 に答える
0

これはこの特定のケースには当てはまりませんが、同じエラーがスローされたが、指定されたメンバー型が 1 で後置固定された選択の列であるという同様の問題がありました....これは、同じものを返すためでした私の選択で列を2回....例:-

SELECT
    CustomerId,
    FirstName,
    LastName,
    CustomerId
FROM
    Customers
于 2016-08-10T11:15:04.073 に答える
0

列のエイリアス名を指定せずに選択を使用している可能性があります。

于 2015-08-13T11:35:20.983 に答える