2つのテーブルに基づいてTableAdapterのFillByをどのようにフィルタリングしますか?

StackOverflow https://stackoverflow.com/questions/410148

質問

Windows FormアプリケーションでVS2008 C#ExpressとNorthwindデータベースを使用しています。

2つのデータグリッドビューのドラッグアンドドロップを使用してマスター詳細バインディングを設定しました(注文と注文詳細を使用しました)。この時点で、すべてが期待どおりに機能します。テーブル内のすべての行を返さないように、OrdersテーブルのフィルターとOrders Detailsテーブルのフィールドに基づいてOrdersテーブルをフィルター処理します。 TableAdapter構成ウィザードで、クエリビルダーを使用して、次のクエリを作成する新しいFillByMyFilterを追加しました。

SELECT Orders。[注文ID]、Orders。[顧客ID]、Orders。[従業員ID]、Orders。[出荷名]、Orders。[出荷住所]、Orders。[出荷市]、Orders。[出荷領域]、                       Orders。[出荷郵便番号]、Orders。[出荷国]、Orders。[出荷ビア]、Orders。[注文日]、Orders。[必須日]、Orders。[出荷日]、                       Orders.Freight FROM INNER JOIN                       [注文の詳細] ON Orders。[注文ID] = [注文の詳細]。[注文ID] WHERE(注文。[出荷名] LIKE N'A% ')AND([注文の詳細]。数量<!> lt; 20)

両方のテーブルを追加することでこれを取得しましたが、元のFillクエリで使用された列のみを返すように、Order Detailsテーブルのフィールドボックスをチェックしませんでした。この時点でマスターテーブルのDataSetをフィルターするだけで、異なる数の列を返そうとはしていません。 Order Detailsの子行は、デフォルトのフィルタリングされていない結果セットのように機能します。

今、問題:[クエリの実行]ボタンをクリックすると、問題なく動作します。デザイナーが作成したデフォルトのFillを使用して、1078ではなく上記のクエリから53行を取得します。元の塗りつぶしクエリと同じ列を返します。ただし、アプリケーションを実行しようとすると、次の制約エラーが表示されます。

<!> quot;制約の有効化に失敗しました。 1つ以上の行に、非ヌル、一意、または外部キー制約に違反する値が含まれています。<!> quot;

何が間違っているのですか?

更新:ウィザードによって作成された内部結合が原因で、制約エラーが発生していると思います。 LEFT JOINを使用するようにクエリを編集すると、ウィザードはそれをINNER JOINに戻します。

私の質問は、親テーブルと子テーブルの両方の基準に基づいて、親テーブル(Orders)のレコードをフィルタリングする方法として残っています。次のテストは、ストアドプロシージャを試して使用することですが、TableAdapterカスタムFillByメソッドだけを使用することを知りたいです。

よろしく、

DeBug

役に立ちましたか?

解決 3

回答を投稿していただいたすべてに感謝します。 TableAdapterウィザードとNorthwind型付きデータセットを使用してどのように実行したかを示します。

1)xsdデザイナーで親テーブルを右クリックして、クエリを追加または構成します。 2)<!> quot; Next <!> quot;をクリックします。ウィザードの<!> quot;クエリビルダー<!> quot;ボタン。 [クエリビルダー]ボタンをクリックして、クエリビルダーモードを開始します。 3)デザインペインで右クリックして子テーブルを追加します。両方のテーブルとそれらを接続するデフォルトの制約が必要です。 4)フィルタする子テーブルの列をクリックして(このチェックマークは後で削除されます)、条件ペインに追加してフィルタできるようにします。 5)親列と子列のフィルターを追加します。この例では、LIKE 'A%'のShip Nameと注文数量<!> ltをフィルタリングしました。 20。

この時点で、[クエリの実行]ボタンをクリックしてクエリをテストできることに注意してください。 Northwind DB for SQL 2008 Compact Editionを使用すると、53行が返されます。この時点でそれを保存すると、結果セットに重複する主キーがあるため、実行時に失敗します。そのため、次の数ステップでそれらを取り除きます。

6)条件ペインで、以前に追加した子テーブル列のチェックを外します。フィルターは残り、デザインペインでも同じ列のチェックが外されます。クエリを実行すると、53行ありますが、子テーブル列はありません。 7)デザインペインを右クリックして、<!> quot; Group By <!> quot;を追加します。この時点で、このクエリを実行すると、注文IDに重複がないはずです。ちょうど29行が返されました。 8)[OK]をクリックし、次に<!> quot; Next <!> quot;をクリックします。新しいFillByクエリを保存するまでボタンをクリックします。 9)新しいFillByを使用するようにソースコードを変更します。

アプリケーションを実行すると、クエリの実行ボタンが返したのと同じ29行のフィルター処理された親テーブルを取得しました。子テーブルは期待どおりに機能し、<!> ltの量を含む少なくとも1つの子行が含まれていました。 20。

実際のアプリケーションでは、ストアドプロシージャまたはLINQを使用する方が良いと思います。しかし、この問題に頭を悩まされたので、<!> quot;それを適合させました<!> quot; (少なくとも私にとっては)挑戦だったからです。

他のヒント

この記事には、問題の原因となっている行を正確に特定するためのトラブルシューティングの提案が含まれています。

DataSet hell-<!> quot;制約を有効にできませんでした。 1つ以上の行に値が含まれています。...<!> quot;

Orders.Designer.cs(私がVBで作業しているように推測)を見ると、おそらく(主キーの)Ordersで定義された一意の制約が表示されます。

問題を疑うのは、クエリを実行すると、<!> gt; 1 OrderDetails.Quanity <!> gt; 20 ....そのため、その順序は結果セットで2回返され、主キーに違反します。

試してください: SELECT * [注文名] [出荷名] LIKE '%whatever%AND OrderID in(OrderDetailsからOrderIDを選択、数量<!> lt; 20)

これはおそらく非常に非効率的な方法です。oracleではIN()の代わりにEXISTS()を使用しますが、同等のSQLサーバーがわかりません。

この回答が得られたらいいのですが、そうでない場合は、考えてみてください。

データセットで、OrderとOrderDetail DataTablesの間に関係がある場合、FK制約のように機能します。そのため、子テーブル(OrderDetail)には、対応する親(Order)レコードを持たないレコードは存在できません。したがって、上記のクエリを使用してOrder DataTableを更新すると、OrderDetailテーブルに子行が残っており、更新後は親(Order)レコードへの参照がなくなります。ただし、Order DataTableを更新する場合は、OrderDetailデータテーブルも更新するか、2つのDataTable間の関係を削除する必要があります。

これが役立つことを願っています...

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top