首页 新闻 会员 周边 捐助

请教如何在不使用OleDbCommandBuilder情况下使用OleDbDataAdapter更新Access数据库记录

0
悬赏园豆:100 [已解决问题] 解决于 2020-03-24 23:33

各位好!

本人最近在学习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     }
复制代码
syzcyyx的主页 syzcyyx | 初学一级 | 园豆:78
提问于:2020-03-16 11:09
< >
分享
最佳答案
0

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

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

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

syzcyyx | 初学一级 |园豆:78 | 2020-03-24 23:30
其他回答(1)
0

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

收获园豆:100
邀月 | 园豆:25475 (高人七级) | 2020-03-16 15:33

你好!

这个MSDN的例子我看过,但是本人功底不够,实在是看不懂,你可否针对我的实际需求,具体说明下?

此例子的中文链接:

https://docs.microsoft.com/zh-cn/dotnet/api/system.data.oledb.oledbdataadapter.updatecommand?view=netframework-4.8

支持(0) 反对(0) syzcyyx | 园豆:78 (初学一级) | 2020-03-16 17:04

我写了如下语句,运行后没有任何反应。

 1 private void Btn_Update2(object sender, RoutedEventArgs e)
 2         {
 3             //使用OleDbDataAdapter的Update方法
 4             OleDbCommand updateCommand = new OleDbCommand()
 5             {
 6                 CommandText = "UPDATE T0101_公司情况表 SET 公司名称_PK = ? WHERE 统一社会信用代码 = '91420300063507079P'",
 7                 Connection = connection
 8             };
 9             updateCommand.Parameters.Add("公司名称_PK", OleDbType.VarChar, 255, "公司名称_PK").Value = "公司名称345";
10             dataAdapter.UpdateCommand = updateCommand;
11             dataAdapter.Update(dataTable);
12         }
支持(0) 反对(0) syzcyyx | 园豆:78 (初学一级) | 2020-03-16 17:18

@syzcyyx:
仔细看了下MSDN文档。UpdateCommand的作用是“在 OleDbCommand 期间用于在对应于 Update(DataSet) 中的修改行的数据源中更新记录的 DataSet。”
所以绕不过去OleDbCommandBuilder 。我机器上也没有access,这段代码应该在MSSQL Server版本下可以运行。

private static void update_ds(string constr)
{
using (OleDbConnection conn = new OleDbConnection(constr))
{
conn.Open();
DataSet ds = new DataSet();
string sql = "select * from Students_demo; ";
OleDbDataAdapter adapate = new OleDbDataAdapter(sql, conn);
adapate.Fill(ds, "table1");

            foreach (DataRow datarow in ds.Tables[0].Rows)
            {
                //更新Chn字段为'99',//20->99
                datarow["Chn"] = "99";
            }
            OleDbCommandBuilder builder = new OleDbCommandBuilder(adapate);
            adapate.Update(ds, "table1");

        }
    }
支持(0) 反对(0) 邀月 | 园豆:25475 (高人七级) | 2020-03-16 20:53

@邀月: 

你好,我之所以提出不用OleDbCommandBuilder类的需求,是因为OleDbCommandBuilder类对于基于多表的联合查询无能为力,而在关系型数据库中,这种情况几乎无法避免。
对多表联合查询使用OleDbCommandBuilder,会有下面的报错:

支持(0) 反对(0) syzcyyx | 园豆:78 (初学一级) | 2020-03-16 21:51
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册