41

次のように仮定します。

CREATE PROCEDURE [MySPROC]
AS 
BEGIN

CREATE TABLE #tempSubset(
    [MyPrimaryKey] [bigint]  NOT NULL,
    [OtherColumn]  [int]     NOT NULL)

INSERT INTO #tempSubset (MyPrimaryKey, OtherColumn) 
    SELECT SomePrimaryKey, SomeColumn 
    FROM   SomeHugeTable
    WHERE  LimitingCondition = true

SELECT MyPrimaryKey, OtherColumn 
FROM   #tempSubset
WHERE  SomeExpensiveCondition = true

END

関数のインポートを生成するか、戻り値の型をマップすると、EF は複合型を生成しないか、次のように通知します。

選択したストアド プロシージャまたは関数は列を返しません

これを克服する方法は?

他の回答は、テーブル変数を使用することを提案しています(パフォーマンス上の理由からこれを行うつもりはありません) 。戻り値のスキーマを偽造し、実際のストアド プロシージャをコメント アウトします。他の回答は、ビューで同様のことを行うことを提案していますが、追加することなくこれを行う方法が必要です。不必要なオーバーヘッドや、モデルを更新するためにストアド プロシージャを中断する必要がありますか?

4

4 に答える 4

66
CREATE PROCEDURE [MySPROC]
AS 
BEGIN

--supplying a data contract
IF 1 = 2 BEGIN
    SELECT
        cast(null as bigint)  as MyPrimaryKey,
        cast(null as int)    as OtherColumn
    WHERE
        1 = 2  
END

CREATE TABLE #tempSubset(
    [MyPrimaryKey] [bigint]  NOT NULL,
    [OtherColumn]  [int]     NOT NULL)

INSERT INTO #tempSubset (MyPrimaryKey, OtherColumn) 
    SELECT SomePrimaryKey, SomeColumn 
    FROM   SomeHugeTable
    WHERE  LimitingCondition = true

SELECT MyPrimaryKey, OtherColumn 
FROM   #tempSubset
WHERE  SomeExpensiveCondition = true

END

結果セットに偽のデータ コントラクトを提供することは、問題に対処するための最も簡単でクリーンで最速の方法です。これと同じ問題が、SSIS のデータ ソース コントロールにも存在します。.NET は、到達不能なクエリの "contract" セクションから結果セットを読み取り、複合型のメタデータを提供します。パフォーマンスへの影響はなく、実際の作業を行う SQL をコメント アウトする必要もありません。

于 2013-05-16T18:20:27.073 に答える
53

これをストアド プロシージャ定義の先頭に追加します。

SET FMTONLY OFF
モデルが問題なく一時テーブルからスキーマを推測できるようにしました。おまけとして、契約のための追加のメンテナンスは必要ありません。

例:

SET FMTONLY OFF

CREATE TABLE #tempTable (
    ...
)

...

SELECT * FROM #tempTable 
于 2015-06-11T16:02:13.497 に答える
10

解決策 1 一時テーブルの代わりにテーブル変数を使用します。

解決策 2 Set FMTONLY off を使用します。プロシージャで SQL コマンドを実行すると、新しい複合型を作成するための列情報が取得されます。

解決策 3 これは良い方法ではありませんが、非常に簡単な方法です。ダミーデータを含むselectステートメントを追加するだけでは、1 = 0であるため実行されません。

このリンクで詳細を確認できます

于 2015-09-03T04:49:00.403 に答える