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 )
我想要更新 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 )