1

私は成功せずにグーグルを試しましたが、尋ねられた唯一の質問は解決策が見つからなかったということでした:http ://social.msdn.microsoft.com/Forums/pl-PL/linqtosql/thread/cee9df70-f38d-40be -ab1a-6697fac461d8

SP

@CustomerName varchar(150) = NULL

DECLARE @SQL nvarchar(2000)

SET @SQL =  'SELECT A.[id], A.[startTime], N.firstName AS CustomerForename, N.surname AS CustomerSurname, O.Email AS OfficerEmail, L.Description AS Location, AT.description AS Type, ATC.description AS Category,AD.cancelledById, A.Deleted
FROM [Calendar].[dbo].[Appointments] AS A
INNER JOIN [Calendar].[dbo].[Name] AS N ON A.Id = N.appointmentId 
INNER JOIN [Calendar].[dbo].[Officers] AS O ON A.Officer = O.Id
INNER JOIN [Calendar].[dbo].[Locations] AS L ON A.Location = L.Id
INNER JOIN [Calendar].[dbo].[AppointmentTypes] AS AT ON A.Type = AT.Id
INNER JOIN [Calendar].[dbo].[AppointmentTypeCategories] AS ATC ON AT.category = ATC.Id
INNER JOIN [Calendar].[dbo].[AppointmentDetails] AS AD ON A.Id = AD.appointmentId
WHERE A.[id] > 1'

IF @CustomerName IS NOT NULL
SET @SQL = @SQL + ' AND (CustomerForename LIKE % + @CustomerName + % OR CustomerSurname LIKE % + @CustomerName + %)'

EXECUTE sp_executesql @SQL

LINQ

public IQueryable<Appointment> GetAppointmentsBySearchCriteria(int appointmentId, string customerName, int officer, int location, int type, DateTime to, DateTime from)
{
var data = _db.GetAppointmentsBySearchCriteria(appointmentId,customerName,officer,location,type,to,from);

foreach (var appointment in data)
{

}
}

これは私が受け取るエラーです:暗黙的に型付けされたローカル変数にvoidを割り当てることはできません

以下を追加してみました:

RETURN EXECUTE sp_executesql @SQL

EXECUTE sp_executesql @SQL
RETURN

SPをDBMLにドラッグすると、次のメッセージが表示されます。次のストアドプロシージャのリターンタイプを検出できませんでした。各ストアドプロシージャのリターンタイプを設定します

助けてくれてありがとう。

クレア :-)

4

3 に答える 3

1

ここでの問題は、CustomerNameオブジェクトを渡すと、ストアドプロシージャ内で生成されたSQLが無効になる(そしてSQLインジェクションの対象になる)という事実にあるようです。

'SELECT A.[id], A.[startTime], N.firstName AS CustomerForename, N.surname AS CustomerSurname, O.Email AS OfficerEmail, L.Description AS Location, AT.description AS Type, ATC.description AS Category,AD.cancelledById, A.Deleted 
FROM [Calendar].[dbo].[Appointments] AS A 
INNER JOIN [Calendar].[dbo].[Name] AS N ON A.Id = N.appointmentId  
INNER JOIN [Calendar].[dbo].[Officers] AS O ON A.Officer = O.Id 
INNER JOIN [Calendar].[dbo].[Locations] AS L ON A.Location = L.Id 
INNER JOIN [Calendar].[dbo].[AppointmentTypes] AS AT ON A.Type = AT.Id 
INNER JOIN [Calendar].[dbo].[AppointmentTypeCategories] AS ATC ON AT.category = ATC.Id 
INNER JOIN [Calendar].[dbo].[AppointmentDetails] AS AD ON A.Id = AD.appointmentId 
WHERE A.[id] > 1
 AND (CustomerForename LIKE % + @CustomerName + % OR CustomerSurname LIKE % + @CustomerName + %)' 

CustomerForenameが「%+ @CustomerName +%」のようになることはありません。sp_executeSQL呼び出しにパラメーターを渡していない。代わりに、CustomerNameパラメーターの前に%ワイルドカードを追加してから、次のようにセカンダリwhere句を追加します。

IF @CustomerName IS NOT NULL   
SET @SQL = @SQL + ' AND (CustomerForename LIKE @CustomerName OR CustomerSurname LIKE @CustomerName)'

次に、次のようにsp_ExecuteSqlを呼び出します。

EXECUTE sp_executesql @SQL, N'@CustomerName NVarChar(150)', @CustomerName

これで、実際にprocから結果セットを取得する必要があります。これにより、sprocの戻りタイプを判別できないという問題が解決する場合があります。そうでない場合は、LINQ to SQLデザイナ(またはDBML)で手動で戻り型を作成し、それをストアドプロシージャの戻り型として明示的に設定する必要があります。または、データベースからsprocをドラッグし、新しく作成したタイプにドロップして、デザイナから直接リターンタイプを自動的に割り当てることもできます。

デザイナよりもストアドプロシージャの戻り型の検出に優れている可能性があるため、SqlMetalを使用してdbmlを生成することもできます。

于 2012-07-03T14:38:50.613 に答える
0

DBMLを使用していて、MSSQLStudioで手動でs/pを作成する場合。以下を行ってください。

  1. データベースからストアドプロシージャを削除し、再作成します。
  2. MS SQL Studioで新しく作成したストアドプロシージャを使用してテストを実行し、データが返されることを確認します。
  3. DBMLデザイナからs/pを削除し、保存して再コンパイルし、Visual Studioを再起動して、再度追加します。
  4. 問題が発生した場合は、スクリーンショットとdbmlファイルを投稿して確認してください。
于 2012-07-03T13:31:48.233 に答える
0

ストアドプロシージャ内で動的SQLを使用する場合、Visual Studioがlinqオブジェクトを作成すると、応答の種類がわかりません。(Linqは、強く型付けされた環境でのみ機能するのが好きです)Visual Studioで手動で変更してみることができます。これは、エラーメッセージで指示されていることです。

  • Visual Studioで、DBMLファイルをデザイナービューで開き、通常どおりSPを追加します。
  • エラーメッセージを確認し、デザイナのリストからSPの名前を選択します。右クリックしてプロパティを押します。
  • プロパティダイアログに隠れているので、手動で設定できる「リターンタイプ」があります。それを試して、それから何を得ることができるかを見てください。

ただし、お勧めしません。まず、linqオブジェクトを削除して再作成した場合は、もう一度実行する必要があります。次に、必要なものが得られない可能性があります。設計図に戻って、動的SQLを回避する方法を考え出すことをお勧めします。linqの動的SQLに関するScottGuthrieのこのブログエントリをご覧ください。拡張メソッドを設定すると、これは非常に優れたソリューションになります。

于 2012-07-09T10:03:56.703 に答える