2

WindowsフォームアプリケーションでVS2008C#ExpressとNorthwindデータベースを使用しています。

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

SELECT Orders。[OrderID]、Orders。[Customer ID]、Orders。[Employee ID]、Orders。[Ship Name]、Orders。[Ship Address]、Orders。[Ship City]、Orders。[Ship Region]、 Orders。[ShipPostalCode]、Orders。[Ship Country]、Orders。[Ship Via]、Orders。[Order Date]、Orders。[Required Date]、Orders。[Shipped Date]、Orders.Freight FROM Orders INNER JOIN [注文の詳細]ON注文。[注文ID]=[注文の詳細]。[注文ID]WHERE(注文。[船名] LIKE N'A%')AND([注文の詳細] .Quantity <20)

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

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

「制約を有効にできませんでした。1つ以上の行に、null以外、一意、または外部キーの制約に違反する値が含まれています。」

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

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

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

よろしく、

デバッグ

4

4 に答える 4

2

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

DataSethell-「制約を有効にできませんでした。1つ以上の行に値が含まれています...」

于 2009-01-04T00:54:59.457 に答える
1

回答を投稿してくれたすべての人に感謝します。以下は、TableAdapter ウィザードと Northwind 型指定されたデータセットを使用して行った方法です。

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

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

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

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

実際のアプリケーションでは、ストアド プロシージャまたは LINQ を使用する方がよいと思います。しかし、この問題に頭を悩ませていたので、(少なくとも私にとっては)挑戦だったという理由だけで「適合させました」。

于 2009-01-06T03:12:47.727 に答える
1

Orders.Designer.cs を見ると (私は VB で作業しているので推測します)、Orders で (主キーに対して) 一意の制約が定義されていることがわかります。

問題は、クエリを実行すると、1 つ以上の OrderDetails.Quanity > 20 を持つ 1 つ以上の個々の注文が取得されるため、主キーに違反して、結果セットでその注文が 2 回返されることです。

試してください: SELECT * from orders where [Ship Name] LIKE '%whatever% AND OrderID in (数量 < 20 の OrderDetails から OrderID を選択)

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

于 2009-01-05T22:15:01.573 に答える
0

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

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

お役に立てれば...

于 2009-01-05T14:43:11.423 に答える