2009-01-04 79 views
2

我在Windows Form應用程序上使用VS2008 C#Express和Northwind數據庫。如何基於兩個表篩選TableAdapter的FillBy?

我使用拖放來設置兩個datagridviews的主詳細信息綁定(我使用了訂單和訂單詳細信息)。在這一點上,一切都按預期工作。因此,爲了不返回表中的每一行,我想根據Orders表的過濾器以及Orders Details表中的字段過濾Orders表。在TableAdapter配置嚮導中,我使用查詢構建器添加了一個新的FillByMyFilter,它創建了以下查詢:

SELECT Orders。[Order ID],Orders。[Customer ID],Orders。[Employee ID],Orders。 [船名],[訂單] [訂單] [訂單] [訂單] [訂單] [訂單] [訂單] [訂單] [訂單] [訂單] [訂單] [訂單日期],訂單[需要日期],訂單。[發貨日期], 訂單。貨運 從訂單內部聯接 [訂單詳細信息]開啓訂單[訂單ID] = [訂單詳細信息]。 ] WHERE(訂單。[船名] LIKE N'A%')和([訂單明細]。數量< 20)

我通過添加這兩個表得到了這一點,但沒有檢查Order Details表中的任何字段框,以便它只返回在原始Fill查詢中使用的列。我只是在此時試圖過濾主表中的DataSet,而不返回不同數量的列。訂單明細的子行仍然應該像默認的未經過濾的結果集一樣工作。

現在的問題:當我點擊執行查詢按鈕,它工作正常。我從上面的查詢中得到53行,而不是使用設計者創建的默認填充1078。它返回與原始填充查詢相同的列。但是,當我嘗試運行該應用程序時,出現以下約束錯誤:

「無法啓用約束,一行或多行包含違反非空,唯一或外鍵約束的值。

我在做什麼錯?

更新:我想我得到了約束錯誤,因爲嚮導創建的INNER JOIN。如果我編輯查詢以使用LEFT JOIN,則嚮導會將其更改回INNER JOIN。

我的問題仍然是如何根據Parent和Child表中的條件過濾父表(Orders)中的記錄。我的下一個測試是嘗試使用存儲過程,但想知道只使用TableAdapter自定義FillBy方法。

問候,

調試

回答

1

感謝所有發佈的答案。以下是我如何使用TableAdapter嚮導和Northwind類型數據集完成的。

1)右鍵單擊xsd設計器中的父表以添加或配置查詢。 2)點擊向導中的「下一步」按鈕,直到看到「查詢生成器」按鈕。單擊「查詢生成器」按鈕以進入查詢生成器模式。 3)右鍵單擊並在設計窗格中添加子表。你應該有兩個表和連接它們的默認約束。 4)單擊要過濾的子表上的列(此複選標記將稍後移除),以便將其添加到標準窗格,以便您可以對其進行過濾。 5)爲Parent和Child列添加過濾器。在這個例子中,我過濾了Ship Name LIKE'A%'和訂單數量< 20.

請注意,此時您可以通過單擊Execute Query按鈕來測試您的查詢。使用Northwind DB for SQL 2008精簡版我得到53行返回。如果在此時保存它,則由於結果集中重複的主鍵,它會在運行時失敗。所以接下來的幾個步驟將擺脫他們。

6)在標準窗格中,取消選中先前添加的子表列。過濾器將保留,同樣的列現在也將在設計窗格中取消選中。如果你運行查詢,你仍然有53行,但沒有子表列。 7)右鍵單擊設計窗格並添加「分組依據」。此時,執行此查詢時,您應該在訂單ID中沒有重複項。我正好返回了29行。 8)點擊確定,然後點擊「下一步」按鈕,直到保存新的FillBy查詢。 9)更改您的源代碼以使用新的FillBy。

當我運行應用程序時,我得到了與執行查詢按鈕返回的29行相同的過濾父表。子表按照預期工作,並且至少包含一個子行,其中包含數量爲< 20.

對於真實世界的應用程序,我認爲使用存儲過程或LINQ會更好。但是這個問題讓我撓了撓腦筋,所以我「適應了」,僅僅因爲這是一個挑戰(至少對我而言)。

2

本文包含一些故障排除建議以查明確切行導致了問題:

DataSet hell - "Failed to enable constraints. One or more rows contain values...."

+0

謝謝交鑰匙!您提供的鏈接非常豐富。我認爲這個問題與TableAdapter嚮導使用INNER JOIN的方式有關(即使我將它更改爲嚮導將它放回)。這將帶回重複的行並破壞主鍵約束。我會嘗試下一個存儲過程。 – user45191 2009-01-04 18:19:16

+0

鏈接已移至 - > http://osherove.com/blog/2004/10/3/dataset-hell-failed-to-enable-constraints-one-or-more-rows-c.html – 2012-06-01 19:07:26

+0

謝謝John ,我更新了新鏈接。 – Turnkey 2012-06-01 19:12:53

0

希望你得到這個回答,但如果沒有,給這一個想法。

在您的數據集中,如果Order和OrderDetail DataTables之間存在關係,那麼它的工作原理有點像FK約束。因此,子表(OrderDetail)中沒有記錄的父記錄沒有相應的父(訂單)記錄。因此,當您刷新Order DataTable時,可能會發生什麼情況,使用上面提到的查詢,OrderDetail表中仍有子行,它們將會刷新Parent(Order)記錄,刷新後將不再存在這些記錄。也就是說,如果刷新Order DataTable,則還需要刷新OrderDetail數據表,或者刪除兩個DataTable之間的關係。

希望這有助於...

1

如果您在Orders.Designer.cs(猜測,因爲我在VB我的工作)看看,你可能會看到訂單上定義的唯一約束(主鍵)。

我懷疑問題是,當你運行你的查詢時,你會得到一個或多個具有> 1 OrderDetails.Quanity> 20的單個訂單......所以,該訂單將在你的結果集中返回兩次,違反主鍵。

嘗試: SELECT * FROM訂單其中[船名] LIKE「%任何%和訂單ID中(從訂單明細選擇的OrderID其中數量< 20)

這可能是一個非常低效的方式做到這一點,在甲骨文你會使用EXISTS()而不是IN(),但我不知道SQL Server的等效。