web-dev-qa-db-ja.com

LINQ toSQL-ストアドプロシージャの戻り値の型を変更できません

特定のストアドプロシージャをVS2008 dbmlデザイナにドラッグすると、戻り値の型が「none」に設定されて表示され、読み取り専用であるため、変更できません。デザイナーコードはそれをintを返すものとして示しており、それを手動で変更すると、次のビルドで元に戻されます。

しかし、別の(ほぼ同一の)ストアドプロシージャを使用すると、戻り値の型を問題なく変更できます(「自動生成された型」から必要なものに変更できます)。

私は2台の別々のマシンでこの問題に遭遇しました。何が起こっているのか分かりますか?

動作するストアドプロシージャは次のとおりです。

USE [studio]
GO
/****** Object:  StoredProcedure [dbo].[GetCourseAnnouncements]    Script Date: 05/29/2009 09:44:51 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER OFF
GO
CREATE PROCEDURE [dbo].[GetCourseAnnouncements]
    @course int
AS
SELECT * FROM Announcements WHERE Announcements.course = @course
RETURN

そして、これはしません:

USE [studio]
GO
/****** Object:  StoredProcedure [dbo].[GetCourseAssignments]    Script Date: 05/29/2009 09:45:32 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER OFF
GO
CREATE PROCEDURE [dbo].[GetCourseAssignments]
    @course int
AS
SELECT * FROM Assignments WHERE Assignments.course = @course ORDER BY date_due ASC
RETURN
20
Kyle Ryan

さて、私は問題を見つけました...ある種。テーブル「Assignments」の名前を変更し、保存されているプロシージャを更新するのを忘れたため、DBML設計者は混乱しました。しかし、ストアドプロシージャを更新し、DBMLデザイナから削除して再読み込みした後でも、機能しませんでした。

これは、ここで説明した問題とほぼ同じです: http://forums.asp.net/t/1231821.aspx

これは、ストアドプロシージャをデータベースから削除して再作成し、DBMLデザイナから削除し、再コンパイルしてVisual Studioを再起動し、再度追加した場合にのみ機能しました。 Visual StudioDBMLデザイナーで「更新」の問題が発生したのはこれが2回目です...

5
Kyle Ryan

私もこの問題を何度か見ました。何が原因かはわかりませんが、それを乗り越えるための非常に簡単な方法に出くわしました。 .dbmlファイル内のxmlを手動で編集する必要がありますが、非常に簡単な編集です。

ソリューションエクスプローラーでデータコンテキストの.dbmlファイル(.layoutファイルやdesigner.csファイルではない)を右クリックし、XMLエディターで開きます。 <Function> ... </Function>ブロックにリストされているストアドプロシージャを見つける必要があります。 <Type> ... </Type>ブロックにリストされている戻り値の型として設定するカスタムクラスも見つける必要があります。

ステップ1は、カスタムクラスに識別子を与えることです。これを行うには、次のように「Id」タグを追加し、dbmlファイル内で一意であることを確認します。

<Type Name="MyCustomClass" Id="ID1">

ステップ2は、新しくIDされた型を戻り値の型として使用するように関数に指示することです。これを行うには、<Function>ブロック内の次のような行を置換します。

<Return Type="System.Int32" />

<ElementType IdRef="ID1" />

ファイルを保存して終了し、再構築します。完了。 .dbmlファイルをデザインモードで再度開いて、次のことを確認します。これで、プロシージャの戻り値の型としてカスタムクラスが設定されます。

19
Eric King

同様のマッピングの問題がありましたが、私の場合は原因を見つけました。

呼び出されるプロシージャまたはサブプロシージャに次のような一時オブジェクトがある場合

CREATE TABLE #result (
   ID INT,
   Message VARCHAR(50)
)

これらの一時的なものを何も選択しなくても、問題が発生します。

タイプはセッションコンテキストのプロシージャの外部で変更される可能性があるため、マッパーにはこれらの一時オブジェクトに関する一般的な問題があります。一時的なオブジェクトはマッパーにとってタイプセーフではなく、マッパーはそれらの使用を拒否します。

それらをテーブル変数に置き換えると、ビジネスに戻ります

DECLARE @result AS TABLE (
   ID INT,
   Message VARCHAR(50)
)
13
Chris

私はより良い解決策のために Tonyによって提供されたリンク をたどりました(Arashのものと同じ答え)

  • ストアドプロシージャにSET FMTONLY OFFを追加するときに考慮すべきことがあるので、ブログ、特に最後の部分を読んでください。

追加するとき

 SET FMTONLY OFF

ストアード・プロシージャーの最初に、それをDBMLにロードします。
LINQ2SQLは実際のストアドプロシージャを実行します。

正しい戻りテーブルオブジェクトタイプを取得するには、
上記のストアドプロシージャは、パラメータなしで呼び出されたときに何かを返す必要があります。
つまり:
1。すべての入力パラメータにデフォルト値を設定する
2。 SPが少なくとも1行のデータを返すことを確認してください-これは私がつまずいた場所です

create table #test ( text varchar(50) );
insert into #test (text) values ('X'); -- w/o this line, return type would be Int32
select * from #test; -- SP returns something, proper object type would be generated
return;
9
Sanjaya.Tio

私はなんとか簡単な方法を考え出すことができました。それは当時は明らかではありませんでしたが、書き留めると簡単に聞こえます。

  1. .dbmlファイルのデザインサーフェスからストアドプロシージャを削除します
  2. [すべてのファイルを保存]をクリックします
  3. ストアドプロシージャのリストでサーバーエクスプローラーの[更新]をクリックします
  4. ストアドプロシージャを.dbmlファイルのデザインサーフェスに追加(ドラッグ)します
  5. [すべて保存]をクリックします
  6. [ビルド]をクリックします
  7. Designer.csコードファイルを確認すると、新しいバージョンのストアドプロシージャ用に更新されたC#コードがあります。

チェック http://www.high-flying.co.uk/C-Sharp/linq-to-sql-can-t-update-dbml-file.html

5
High-Flying

同じ問題が発生しましたが、spがFTSを使用している場合にのみ発生し、dbmlデザイナーを「ごまかす」ことでした。fts言語のものを削除して完全に機能するようになり、戻り値の型を変更できるようになりました。後で私はspに行き、再びftsを追加して、完璧に動作します!。この助けを願っています。

1
Rubenz

この問題を回避する方法は次のとおりです。

  1. 「setfmtonlyoff;」を追加します。ストアドプロシージャの最初に。
  2. そのステートメントを追加した後、get DBMLは、ストアドプロシージャのコードを生成します。

ストアード・プロシージャーの戻り値の型がDBMLコードでまだ「int」である場合は、ストアード・プロシージャーのコード全体をコメント化し、戻り値の型と名前が元のSELECTステートメントと一致する新しいSELECTステートメントを作成して、DBMLにコードを再生成させます。それは機能しなければなりません!

1
Arash

@Rubenzに感謝します。私も、ストアドプロシージャでFTS(全文検索)を使用していて、手順は機能しました。

ストアドプロシージャからFTSセクションにコメントを付け、ストアドプロシージャを.dbmlに追加してから、FTSセクションのコメントを解除して元に戻しました。

1
adamsproul

これは古い質問だと思いますが、上記の提案は私を正しい方向に向けましたが、私の場合はうまくいきませんでした。上記のように、VisualStudioのXMLエディターでdbmlファイルを編集することになりました。

ファイルに移動したら、ストアドプロシージャの関数セクションを探します。ほとんどの場合、戻り値の型を定義するセクション– ElementType –は表示されません。別の関数(ストアドプロシージャ)のフィールドを編集し始めましたが、これは面倒で問題が発生する可能性があることがわかりました。

ElementTypeからすべての列定義を削除することにしましたが、ElementTypeセクションを残してファイルを保存します。次に、ストアドプロシージャをデザイナから削除し、再度追加しました。次に、ElementType内の正しい列に入力しました。美しく働いた。

0
T. DeVoe

これは、ストアドプロシージャのパラメータとしてSQLユーザー定義型を使用する場合にも発生します

http://alejandrobog.wordpress.com/2009/09/23/linq-to-sql-%e2%80%94-can%e2%80%99t-modify-return-type-of-stored -手順/

0

OK、Designer.csコードで何も変更したくありませんでした。別の問題があり、それがストアドプロシージャに関連していないことはわかっていました(とにかく一時テーブルを使用していませんでした)。

データベースからspを削除し、モデルを更新するだけでは、まったく役に立ちませんでした。作成された新しいモデルにも同じ問題がありました...

私が見つけたのは、何らかの理由で私のspのコピーがDatabaseModel-> FunctionImportsで作成されたということです。

私がしたことは、関数のインポートで重複したオブジェクトを削除し、モデルを更新したことです。出来た!

よろしく、クリス

0
Chris Ciszak