C# SqlCommandBuilder , CommandUpdate - 如何根据 select 和外连接表编写正确的更新

C# SqlCommandBuilder , CommandUpdate - how to write correct update based on select with outer join tables

我想要更新 2 个字段:p.FlagaWaznosci 和 p.Notatka

我的 select 看起来像:

Select  DISTINCT p.id,p.Model_Number,p.Product_Name,p.Website_Link,p.Entry_date,p.LastUpdate_date,p.PrzydzialRozmiarow_ID,p.FlagaWaznosci,p.Notatka,pr.NazwaRozmiarowki,wd.LINK_StockX 
from Products p with(nolock)
left outer  join Widok_Model_Sklep_Stockx_Linki wd with(nolock) on wd.Product_ID = p.id 
left outer join PrzydzialRozmiarow pr with(nolock) on pr.id = p.PrzydzialRozmiarow_ID 
inner join Shops s with(nolock) on s.ID = p.Shop_ID 

只有外部联接才能获取我需要在 gridview 中显示的正确数据。现在,当值 p.FlagaWaznosci 或 p.Notatka 更改时,我想将更新保存在我的数据库中。

我尝试使用

//loads dataand fill to gridview
 DataTable WszystkieProduktyDlaDanegoSklepu;
 SqlDataAdapter sda555123 = new SqlDataAdapter("here is my select", conn123);
 sda555123.Fill(WszystkieProduktyDlaDanegoSklepu);
 
 //later update table Prooducts and save changed on p.Notatka and p.FlagaWaznosci
 cmdbl = new SqlCommandBuilder(sda555123);
 cmdbl.ConflictOption = ConflictOption.OverwriteChanges;
 sda555123.Update(WszystkieProduktyDlaDanegoSklepu);

但是这样我有错误

所以我搜索了很多,发现:我必须自己写CommandUpdate。

所以... sda555123.UpdateCommand 而且我不知道如何在更新命令中为它编写自己的更新。

SQL 服务器中的更新应如下所示:

Update Products
set FlagaWaznosci = @Flagawaznosci from my sda555123,
Notatka = @Notatka from my sda555123 
where id = @ p.ID from my sda555123 

我的命令更新在这里应该是什么样子?

编辑 1:

我尝试添加:WszystkieProduktyDlaDanegoSklepu.PrimaryKey = new DataColumn[] { WszystkieProduktyDlaDanegoSklepu.Columns["id"] } 但什么都没有。还是这个错误。

请单独更新您的 table,因为在 join 中您刚刚看到两个或两个以上的 table 合并为一个 table 表格。但是你不能对

做任何 crud 操作

我会通过改变方法而不是改变 SqlDataAdapter 的更新命令来解决问题。

鉴于您查询中的 Products.id 在结果集中是唯一的:

1- 创建一个临时 table(本地或全局),其列与以 id 作为主键的查询结果相同。

2- 使用您的 select 语句将数据插入临时 table。

3- DataAdatper.selectQuery.commandText 设置为“select * 来自 TempTable”

4- 更新命令现在基于一个简单的 select 语句,因此 datagridview/datatable 中的任何更改都可以使用 dataadapter.update 更新到临时 table (数据table)

5- 至于最后的数据库更新,你可以使用下面的语句

Update Prd
set Prd.FlagaWaznosci = TempTable.FlagaWaznosci ,Prd.Notatka = TempTable.Notatka  etc.. all the fields that need to be updated  
from my Products as Prd 
Inner Join TempTable on TempTable.id = Prd.id

请注意,(5) 中的更新将影响所有行,甚至是未更改的行。 要解决此问题,您可以按以下步骤进行

1- 将更改的 ID 保存在列表中。

List<string> lst = new List<string>();
foreach(DataRow dr in datatable.GetChanges(DataRowState.Modified))
{
 lst.add(dr["id"].ToString());
}

2- 将您的列表转换为要与 (5) 中的查询连接的字符串值

 String strchange = String.Join(",",lst); //will give you id1,id2,...
 //The update query becomes
 Update Prd
 set Prd.FlagaWaznosci = TempTable.FlagaWaznosci ,Prd.Notatka = 
 TempTable.Notatka  etc.. all the fields that need to be updated  
 from my Products as Prd 
 Inner Join TempTable on TempTable.id = Prd.id
 Where Prd.id In ( strchange )