次の方法で共有


よく寄せられる質問 (LINQ to SQL)

更新 : November 2007

ここでは、LINQ を実装するときに発生する可能性のある一般的な問題の対処法について説明します。

その他の問題については、「トラブルシューティング (LINQ to SQL)」を参照してください。

接続できない

Q. データベースに接続できません。

A. 接続文字列が正しいこと、および SQL Server のインスタンスが実行中であることを確認してください。また、LINQ to SQL では、名前付きパイプ プロトコルを有効にする必要があります。詳細については、「チュートリアルによる学習 (LINQ to SQL)」を参照してください。

データベースの変更内容が失われる

Q. データベース内のデータを変更しましたが、アプリケーションを再実行すると、変更が元に戻っています。

A. 変更結果をデータベースに保存するために、必ず SubmitChanges を呼び出してください。

データベース接続: どれほどの時間開いているか

Q. データベース接続は、どれほどの時間開いていますか。

A. 通常、接続は、クエリ結果を処理するまで開いた状態を保ちます。すべての結果を処理するのに時間がかかる可能性がある場合、結果をキャッシュに入れることが可能であれば、クエリに対して ToList<TSource> を適用してください。通常のシナリオでは、各オブジェクトが一度だけ処理されるため、DataReader と LINQ to SQL のどちらの場合もストリーミング モデルがより優れています。

接続が厳密にどのように使用されるかは、以下に応じて異なります。

  • 接続オブジェクトを使って DataContext が作成されている場合は、接続状態。

  • 接続文字列の設定 (たとえば、複数のアクティブな結果セット (MARS) の有効化)。詳細については、「複数のアクティブな結果セット (MARS)」を参照してください。

クエリを使用しない更新

Q. データベースに対してあらかじめクエリを実行せずに、テーブル データを更新することは可能ですか?

A. LINQ to SQL にはセットベースの更新コマンドはありませんが、次のいずれかの技法を使用すると、事前のクエリなしで更新できます。

  • ExecuteCommand を使って SQL コードを送信する。

  • オブジェクトの新しいインスタンスを作成し、更新に関連したすべての現在値 (フィールド) を初期化する。その後、Attach を使ってオブジェクトを DataContext に関連付け、更新対象のフィールドを変更します。

予期しないクエリ結果

Q. 予期しない結果がクエリから返されます。どうなっているのか調べる方法はありますか。

A. LINQ to SQL には、生成された SQL コードを調べるためのツールがいくつか用意されています。このうち、最も重要なものは Log です。詳細については、「デバッグのサポート (LINQ to SQL)」を参照してください。

予期しないストアド プロシージャ結果

Q. 戻り値が MAX() によって計算されるストアド プロシージャがあります。このストアド プロシージャを O/R デザイナ サーフェイスにドラッグすると、戻り値が正しくありません。

A. LINQ to SQL には、ストアド プロシージャを介して、データベースによって生成される値を返す方法が 2 つあります。

  • 出力結果に名前を付ける。

  • 出力パラメータを明示的に指定する。

間違っている出力例を以下に示します。LINQ to SQL は結果をマップできないため、常に 0 が返されます。

create procedure proc2

as

begin

select max(i) from t where name like 'hello'

end

出力パラメータを使用して正しい出力をする例を次に示します。

create procedure proc2

@result int OUTPUT

as

select @result = MAX(i) from t where name like 'hello'

go

出力結果に名前を付けて正しい出力をする例を次に示します。

create procedure proc2

as

begin

select nax(i) AS MaxResult from t where name like 'hello'

end

詳細については、「ストアド プロシージャによる操作のカスタマイズ (LINQ to SQL)」を参照してください。

シリアル化のエラー

Q. シリアル化を試みると、「アセンブリ ... の型 'System.Data.Linq.ChangeTracker+StandardChangeTracker' はシリアル化可能として設定されていません。」というエラーが発生します。

LINQ to SQL のコード生成では、DataContractSerializer のシリアル化がサポートされます。XmlObjectSerializer および BinaryFormatter はサポートされません。詳細については、「シリアル化 (LINQ to SQL)」を参照してください。

複数の DBML ファイル

Q. いくつかのテーブルを共有する複数の DBML ファイルが存在する場合、コンパイラ エラーが発生します。

A. オブジェクト リレーショナル デザイナの Context Namespace プロパティと Entity Namespace プロパティを、各 DBML ファイルの個別の値に設定してください。この手法により、名前および名前空間の競合を防ぐことができます。

挿入または更新で、データベース生成値を明示的に設定しなくても良いようにする

Q. あるデータベース テーブルに DateCreated という列があり、その既定値は SQL Getdate() です。LINQ to SQL を使用して新しいレコードを挿入しようとすると、値が NULL に設定されます。データベースの既定値が設定されるようにするには、どうしたらいいですか。

A. ID 列 (自動インクリメント)、rowguidcol 列 (データベースが生成した GUID)、およびタイムスタンプ列の場合には、LINQ to SQL はこのような状況に自動的に対処します。それ以外の場合には、手動で IsDbGenerated=true プロパティと AutoSync=Always/OnInsert/OnUpdate プロパティを設定する必要があります。

複数の DataLoadOptions

Q. 最初の読み込みオプションを上書きせずに、追加の読み込みオプションを指定できますか?

A. はい。次の例のように、最初のオプションは上書きされません。

Dim dlo As New DataLoadOptions()
dlo.LoadWith(Of Order)(Function(o As Order) o.Customer)
dlo.LoadWith(Of Order)(Function(o As Order) o.OrderDetails)
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<Order>(o => o.Customer);
dlo.LoadWith<Order>(o => o.OrderDetails);

SQL Compact 3.5 の使用に関するエラー

Q. テーブルを SQL Server Compact 3.5 データベースからドラッグすると、エラーが発生します。

A. SQL Server Compact 3.5 は LINQ to SQL ランタイムではサポートされますが、オブジェクト リレーショナル デザイナではサポートされません。この場合、独自のエンティティ クラスを作成して適切な属性を追加する必要があります。

継承関係でのエラー

Q. オブジェクト リレーショナル デザイナでツールボックスの継承図形を使って 2 つのエンティティを接続すると、エラーが発生します。

A. 関係を作成するだけでは不十分です。識別子の列、基本クラスの識別子の値、派生クラスの識別子の値などの情報を提供する必要があります。

プロバイダ モデル

Q. パブリック プロバイダ モデルを利用できますか?

A. いいえ。使用可能なパブリック プロバイダ モデルはありません。現時点で、LINQ to SQL は SQL Server と SQL Server Compact 3.5 だけをサポートします。

SQL 注入攻撃

Q. LINQ to SQL は SQL 注入攻撃からどのように保護されますか?

A. ユーザー入力を連結して形成される従来の SQL クエリでは、SQL 注入は大きなリスクとなってきました。LINQ to SQL では、クエリで SqlParameter を使用することにより、そのような注入を防止します。ユーザー入力はパラメータ値に変換されます。この手法は、顧客の入力で悪意のあるコマンドが使用されることを防止します。

DBML ファイル内の読み取り専用フラグの変更

Q. DBML ファイルからオブジェクト モデルを作成するとき、特定のプロパティからの setter をどのように除くことができますか?

A. これは高度なシナリオですが、以下の手順に従ってください。

  1. .dbml ファイル内で、IsReadOnly フラグを True に変更することにより、プロパティを変更します。

  2. 部分クラスを追加します。読み取り専用メンバ用のパラメータを使ってコンストラクタを作成します。

  3. 既定の UpdateCheck 値 (Never) がアプリケーションにとって適切な値かどうかを検討します。

    注意 :

    Visual Studio でオブジェクト リレーショナル デザイナを使用している場合は、変更内容が上書きされる可能性があります。

APTCA

Q. System.Data.Linq は、部分的に信頼されているコードによる使用が可能だとマークされていますか?

A. はい。System.Data.Linq.dll アセンブリは、AllowPartiallyTrustedCallersAttribute 属性を使ってマークされる .NET Framework アセンブリに含まれています。このマークがないと、.NET Framework のアセンブリは完全に信頼されたコードによってのみ使用されます。

部分的に信頼される呼び出し元を LINQ to SQL で許可する主なシナリオは、trust 構成が Medium の Web アプリケーションから LINQ to SQL アセンブリにアクセスできるようにする場合です。

ASP.NET コード アクセス セキュリティ
ASP.NET コード アクセス セキュリティ

複数のテーブルからのデータのマッピング

Q. 複数のテーブルから得られるデータを持つエンティティがあります。どのようにマップできますか?

A. データベース内にビューを作成して、エンティティをそのビューにマップすることができます。LINQ to SQL はテーブルの場合と同じ SQL をビュー用に生成します。

メモ :

このシナリオでのビューの使用には、制限があります。この手法は、Table<TEntity> に対して実行される操作が、基になるビューでサポートされるような場合に、最も安全に機能します。どのような操作が意図されるかは、開発者だけが知っています。たとえば、ほとんどのアプリケーションは読み取り専用です。他の多くのアプリケーションは、ビューに対してストアド プロシージャを使用することによってのみ、Create/Update/Delete 操作を実行します。

接続プール

Q. DataContext プールに役立つコンストラクトはありますか?

A. DataContext のインスタンスの再使用はしないでください。DataContext はそれぞれ、特定の 1 つの編集/クエリ セッション用の状態 (ID キャッシュを含む) を保持します。データベースの現在の状態に基づく新しいインスタンスを得るには、新しい DataContext を使用してください。

それでも、基になる ADO.NET 接続プールは使用できます。詳細については、「SQL Server の接続プール (ADO.NET)」を参照してください。

2 番目の DataContext が更新されない

Q. データベース内の値を格納するために、DataContext の 1 つのインスタンスを使用しました。しかし、同じデータベースに対する 2 番目の DataContext では、更新された値が反映されません。2 番目の DataContext インスタンスは、キャッシュされた値を返すようです。

A. この動作は意図されたものです。LINQ to SQL は、最初のインスタンスと同じインスタンス/値を返し続けます。更新の際には、オプティミスティック同時実行が使用されます。元のデータを使ってデータベースの現在の状態を検査し、実際に未変更であることをアサートします。変更されている場合は競合が発生するため、アプリケーションでそれを解決する必要があります。1 つのオプションとして、アプリケーションは、元の状態をデータベースの現在の状態にリセットして、更新を再試行できます。詳細については、「方法 : 変更の競合を管理する (LINQ to SQL)」を参照してください。

また、ObjectTrackingEnabled を false に設定することもできます。この場合、キャッシュと変更追跡が無効になります。その後は、クエリを実行するたびに最新の値を取得できます。

読み取り専用モードで SubmitChanges を呼び出すことができない

Q. 読み取り専用モードで SubmitChanges を呼び出そうとすると、エラーが発生します。

A. 読み取り専用モードでは、変更を追跡するコンテキスト機能が無効になります。

参照

処理手順

トラブルシューティング (LINQ to SQL)

概念

LINQ to SQL におけるセキュリティ

その他の技術情報

リファレンス (LINQ to SQL)