请教如何在不使用OleDbCommandBuilder情况下使用OleDbDataAdapter更新

2020-03-24 22:51发布

问题:

各位好!

本人最近在学习Access数据库。在尝试使用C#语言在WPF项目内进行Access数据库的连接与记录修改。

网上有很多文章将此方面内容,但都是OleDbCommandBuilder和OleDbDataAdapter联合使用,好处很多,但弊端显而易见:一旦查询为基于多表的联合查询,若要修改记录,OleDbCommandBuilder便不可使用。

直接使用OleDbCommand进行操作,本人已经摸索明白。但如何在不使用OleDbCommandBuilder情况下使用OleDbDataAdapter更新Access数据库记录,本人才疏学浅,实在是搞不懂,还请指点。

本人的需求很简单:

1、单独使用OleDbDataAdapter类(不使用OleDbCommandBuilder)

2、使用OleDbDataAdapter类的Update方法,更新所有在datagrid控件内修改了公司名称的数据库记录。(改什么公司名称随意)

Access数据库结构(已去除敏感信息)

该查询实例的Jet-SQL语句:

SELECT T0101_公司情况表.公司名称_PK, T0101_公司情况表.统一社会信用代码, T0301_fdc证件信息表.证件编号
FROM T0101_公司情况表 INNER JOIN T0301_fdc证件信息表 ON T0101_公司情况表.公司名称_PK = T0301_fdc证件信息表.公司名称_FK;

 

WPF项目前端Xaml代码

 1 <Window x:Class="WpfAccess_2.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:WpfAccess_2"
 7         mc:Ignorable="d"
 8         Title="MainWindow" Height="657.812" Width="1276.562">
 9     <Grid>
10         <DataGrid x:Name="dataGrid" Margin="10,198,10,10" AutoGenerateColumns="True"/>
11         <Button x:Name="btn_Read" Content="读取" HorizontalAlignment="Left" VerticalAlignment="Top" Width="212" Margin="10,10,0,0" Height="66" FontSize="20" Click="Btn_Read_Click"/>
12         <Button x:Name="btn_Update" Content="直接更新&#xD;&#xA;Update" HorizontalAlignment="Left" Margin="227,10,0,0" VerticalAlignment="Top" Width="212" Height="66" FontSize="20" Click="Btn_Update_Click"/>
13         <Button x:Name="btn_Clear" Content="清除" HorizontalAlignment="Left" Margin="10,81,0,0" VerticalAlignment="Top" Width="212" Height="66" Click="Btn_Clear_Click" FontSize="20"/>
14         <Button x:Name="btn_Update2" Content="使用&#xD;&#xA;OleDbDataAdapter&#xD;&#xA;更新(Update2)" HorizontalAlignment="Left" Margin="227,81,0,0" VerticalAlignment="Top" Width="212" Height="82" Click="Btn_Update2" FontSize="20"/>
15 
16     </Grid>
17 </Window>

WPF项目后端C#代码

 1     using System;
 2     using System.Collections.Generic;
 3     using System.Linq;
 4     using System.Text;
 5     using System.Threading.Tasks;
 6     using System.Windows;
 7     using System.Windows.Controls;
 8     using System.Windows.Data;
 9     using System.Windows.Documents;
10     using System.Windows.Input;
11     using System.Windows.Media;
12     using System.Windows.Media.Imaging;
13     using System.Windows.Navigation;
14     using System.Windows.Shapes;
15     using System.Data.OleDb;
16     using System.Data;
17 
18     namespace WpfAccess_2
19     {
20         /// <summary>
21         /// MainWindow.xaml 的交互逻辑
22         /// </summary>
23         public partial class MainWindow : Window
24         {
25             public MainWindow()
26             {
27                 InitializeComponent();
28                 InitializeMyComponent();
29             }
30 
31             OleDbConnection connection;
32             OleDbDataAdapter dataAdapter;
33             DataTable dataTable;
34             private void InitializeMyComponent()
35             {
36                 connection = new OleDbConnection()
37                 {
38                     ConnectionString = Properties.Settings.Default.myConnectString
39                     //myConnectString为存放的连接字符串
40                 };            
41                 string selectCommand = "SELECT T0101_公司情况表.公司名称_PK, T0101_公司情况表.统一社会信用代码, T0301_fdc证件信息表.证件编号 FROM T0101_公司情况表 INNER JOIN T0301_fdc证件信息表 ON T0101_公司情况表.公司名称_PK = T0301_fdc证件信息表.公司名称_FK";
42                 dataAdapter = new OleDbDataAdapter(selectCommand, connection);
43                 dataTable = new DataTable();
44             }
45 
46 
47             private void Btn_Read_Click(object sender, RoutedEventArgs e)
48             {
49                 dataTable.Clear();
50                 dataAdapter.Fill(dataTable);
51                 dataGrid.ItemsSource = dataTable.DefaultView;//这句话好像只能放这里,否则datagrid控件内显示不正常。
52             }
53 
54             private void Btn_Update_Click(object sender, RoutedEventArgs e)
55             {
56                 //使用OleDbCommand直接操作数据库。
57                 //OleDbCommandBuilder()只能针对单个表用,使用有限制。
58                 OleDbCommand oleDbCommand = new OleDbCommand()
59                 {
60                     CommandText = "UPDATE T0101_公司情况表 SET 公司名称_PK = @查询参数1 WHERE 统一社会信用代码 = '91420300063507079P'",//使用特定“统一社会信用代码”定位被修改的记录,目前只会这种方式
61                     Connection=connection,
62                 };
63                 OleDbParameter parameter = new OleDbParameter("@查询参数1", OleDbType.VarChar, 50, "公司名称_PK");
64                 Random random = new Random(2);
65                 parameter.Value = "测试公司名称" + random.Next(1, 999);//让名字每次不一样
66                 oleDbCommand.Parameters.Add(parameter);
67 
68                 connection.Open();
69                 oleDbCommand.ExecuteNonQuery();
70                 connection.Close();
71 
72                 dataTable.Clear();
73                 dataAdapter.Fill(dataTable);
74             }
75 
76             private void Btn_Clear_Click(object sender, RoutedEventArgs e)
77             {
78                 dataTable.Clear();
79             }
80 
81             private void Btn_Update2(object sender, RoutedEventArgs e)
82             {
83                 //直接使用OleDbDataAdapter的Update方法,求教各位专家
84             }
85         }
86     }

回答1:

感谢@邀月的耐心解答,但问题并没有得到解决。

经过摸索和查询,我已经自己解决了这个问题,具体解决方法我已经写成了随笔。

解决方法在此,请点击查看。



回答2:

试试构造一个command实例赋值给OleDbDataAdapter的UpdateCommand属性
dataAdapter.UpdateCommand = command;
https://docs.microsoft.com/en-us/dotnet/api/system.data.oledb.oledbdataadapter.updatecommand?view=netframework-4.8