C#学习笔记之使用Access读取Excel表格

一、读取Excel表的内容(使用DataSet)

1、DataSet定义:表示数据在内存中的缓存。可以理解为,将从Excel表中读取出来的数据存入DataSet类中,之后对DataSet进行数据处理,能提高处理的速度。

2、读取Excel文件的内容,通过OLEDB来连接,关键是连接的路径

  • Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + path + ";Extended Properties=\"Excel 8.0;HDR=NO;IMEX=1\"
  • Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=\"Excel 12.0;HDR=NO;IMEX=1\"

① Provider:使用的是OLEDB连接;

② Data Source + path:为Excel文件所在完整路径;

③ Extended Properties:指定Excel的版本,需与读取的Excel文件保持一致;

④ 参数Excel 8.0 表示对于Excel97以上到2003版本都用Excel 8.0;2007或2010的都用Excel 12.0;

⑤ HDR = YES:表示第一行是标题,不做为数据使用;HDR = NO:表示第一行不是标题,做为数据来使用。系统默认为YES;

⑥ IMEX(IMport EXport mode)设置:有三种模式

  • IMEX = 0:汇出模式,这个模式开启的 Excel 档案只能用来做“写入”用途;
  • IMEX = 1:汇入模式,这个模式开启的 Excel 档案只能用来做“读取”用途
  • IMEX = 2:连结模式,这个模式开启的 Excel 档案可同时支援“读取”和“写入”用途

3、读取不同的Sheet,方式跟SQL类似:使用字符串 "SELECT * FROM [Sheet1$]" 表示。

string connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=” + path+ ";Extended Properties=\”Excel 12.0;HDR=NO;IMEX=1\"";
string sqlSelect = "SELECT * FROM [Sheet1$]";//Sheet1表示工作表的名称,可根据实际表格工作表进行设置
OleDbConnection connection = new OleDbConnection(connectionString);
OleDbCommand command = new OleDbCommand(sqlSelect, connection);
OleDbDataAdapter adapter = new OleDbDataAdapter(command);
connection.Open();
adapter.Fill(dataSet);

4、异常处理

①如果出现 External table is not in the expected format.

大多数是因为路径中的OLEDB或者Extented Properties 与当前的Excel文件版本不对应导致。

②如果出现 The "XXXXXXX" provider is not registered on the local machine.

那是因为Platform target配置不当的问题,OLEDB貌似只支持x86, 所以你只需要到项目属性 -> 生成-> 目标平台 -> x86就可以了

③如果出现 未经处理的异常:【未在本地计算机上注册 “Microsoft.ACE.OLEDB.12.0"提供程序】或者【未在本地计算机上注册"Microsoft.Jet.OLEDB.4.0"提供程序】

可能是没有安装组件,进入Microsoft Access官网下载数据库引擎可再发行程序包

下载链接:Download Microsoft Access Database Engine 2010 Redistributable from Official Microsoft Download Center

双击安装包安装即可:

本人所遇问题,在安装完组件后,以完美解决,且前两个问题也没有出现。

二 、界面设计

1、触发浏览按钮,选择Excel文档所在文件夹路径(使用的是 using 语句)

2、触发开始按钮,对数据库进行查找,并将数据缓存至DataSet中

3、选择提取出来的DataSet数据库中的表格DataTable

4、将DataTable中的内容显示在主界面的控件1中,对DataTable表格内某些内容进行提取并处理,将处理后的数据保存至主界面的控件2内

5、软件运行时出现异常中断:Exception from HRESULT: 0x80010100 (RPC_E_SYS_CALL_FAILED)

此次运行代码发现,有以下几个问题:

①在开始对表格数据执行操作时主界面控件处于锁定状态,即无法对主界面执行任何操作(拖动窗体都不行)

②在foreach循环中多次对textBox控件执行操作,会造成软件异常中断

原因为:对表格数据执行操作使用的foreach循环一直在主线程中运行,占用着主线程资源,此时又在同一时间段开启另一段主线程(一直访问控件),两个主线程同时运行,长时间就会出现中断异常。

解决方案:将foreach循环放入异步线程中运行,使读取数据表格内容进入次线程中执行,此时不管对主线程做任何操作,次线程都不会对主线程有影响。异步线程方式为:

Task.Factory.StartNew(()=>
{
  //需要执行的任务
  //本人执行的的有:foreach循环,主界面TestBox控件显示内容等
}).Wait();

 三、代码逻辑

1、主界面程序

private WriteLog writeLog = new WriteLog();
private Configuration configuration;
private OtherConfiguration otherConfiguration;
private const string startString = @"开始读值";
private const string stopString = @"停止读值";
private int excelCount;
private ProductInfo[] productInfos;
//主界面加载
private void FormMain_Load(object sender, EventArgs e)
{
    WriteLog("初始化界面!");
    productInfos = new ProductInfo[255];
    configuration = Configuration.Instance.Read(FilePathStrings.ConfigurantionFilePath);
    otherConfiguration = configuration.OtherConfiguration ?? new OtherConfiguration();
    WriteLog($"加载设置文档路径参数:{otherConfiguration.TestResultPathFile1}");
}
//参数设置控件
private void btnToolSet_Click(object sender, EventArgs e)
{
    WriteLog("设置界面!");
    using (FormSetting setting = new FormSetting())
    {
        if (setting.ShowDialog() == DialogResult.OK)
        {
            configuration = Configuration.Instance.Read(FilePathStrings.ConfigurantionFilePath);
            otherConfiguration = configuration.OtherConfiguration;
            WriteLog($"设置完成并加载设置文档路径参数:{otherConfiguration.TestResultPathFile1}");
        }
        else
            WriteLog($"未进行设置!");
    }
} 
//开始读取数据控件
private void btnToolTest_Click(object sender, EventArgs e)
{
    Task.Factory.StartNew(() =>
    {
        WriteLog($"开始加载!");
        Invoke(new Action(() =>
        {
            btnToolSet.Enabled = false;
            btnToolTest.Text = stopString;
        }));
        foreach (var dataFileString in otherConfiguration.TestResultDataFilePath)
        {
            Invoke(new Action(() => { superGridControl1.Refresh(); }));
            WriteLog($"开始读取所选文件【{dataFileString}】中内容,请稍等...");
            excelCount = 0;
            TestInputDataModel testInputDataModel;
            var currentDataName = ComboBoxEx.GetEnumName<eDataName>(otherConfiguration.DataName);
            switch (currentDataName)
            {
                case eDataName.Convention:
                    testInputDataModel = new TestInputDataModel(dataFileString, ConstStrings.DataNameConvention);
                    break;
                case eDataName.Special:
                    testInputDataModel = new TestInputDataModel(dataFileString, ConstStrings.DataNameSpecial);
                    break;
                default: throw new NotImplementedException("无效类型!");
            }
            //string[] fileStrings = new DirectoryInfo(testResultPathFile1).GetFiles().Select(s => s.Name).ToArray();
            FileInfo[] fileInfos = new DirectoryInfo(testInputDataModel.TestFilePath).GetFiles();
            productInfos = new ProductInfo[fileInfos.Length];
            foreach (var fileData in fileInfos)
            {
                WriteLog($"开始读取表格【{fileData}】中数据,请稍等...");
                ReadExcelData excelData = new ReadExcelData(fileData.FullName, fileData.Extension, testInputDataModel.StartExcelName[0]);
                dynamic dataTable = excelData.OpenExcel().Tables[0];
                productInfos[excelCount] = DisplaysOptimizationTable(testInputDataModel.StartExcelName, dataTable);
                if (productInfos[excelCount] != null)
                {
                    Invoke(new Action(() =>
                    {
                        superGridControl1.PrimaryGrid.DataSource = productInfos;
                        superGridControl1.Refresh();
                        superGridControl1.PrimaryGrid.LastOnScreenRowIndex = (superGridControl1.PrimaryGrid.Rows.Last() as GridRow).Index;
                    }));
                    CreateAndWriteNewExcel(productInfos[excelCount]);
                    excelCount += 1;
                    excelData.Dispose();
                }
                 else WriteLog($"表格【{fileData}】中没有数据!");
            }
        }
        WriteLog($"停止加载!\r\n所选文件夹已全部完成,请重新选择!");
        Invoke(new Action(() =>
        {
            btnToolSet.Enabled = true;
            btnToolTest.Text = startString;
        }));
    }).ContinueWith(t =>
    {
        if (t.IsFaulted)
        {
            if (t != null)
                throw GetInnerException(t.Exception);
        }
    });
}
//创建新表格并将数据写入
private void CreateAndWriteNewExcel(ProductInfo testValue)
{
    Task t0 = Task.Factory.StartNew(() =>
    {
        WriteLog($"将提取数据保存至{ExcelEx.path}中,请稍等...");
        string errorMessage = string.Empty;
        ExcelEx.CreateAndWriteNewExcel(otherConfiguration, testValue, out bool isError, ref errorMessage);
        if (!isError)
            WriteLog($"保存成功!");
        else
            WriteLog($"保存失败,错误信息:{errorMessage}清除异常后请重新提取数据!");
    });
    t0.Wait();
}
//对初始表格进行数据提取
private ProductInfo DisplaysOptimizationTable(string[] excelDataNames, DataTable dataTable)
{
    ProductInfo productInfos = new ProductInfo();
    Task t0 = Task.Factory.StartNew(() =>
    {
        try
        {
            int passCount = 0;
            int failCount = 0;
            int dataIndex = Array.IndexOf(dataTable.Rows[Convert.ToInt32(excelDataNames[1])].ItemArray, excelDataNames[2]);
            int numIndex = Array.IndexOf(dataTable.Rows[Convert.ToInt32(excelDataNames[1])].ItemArray, excelDataNames[3]);
            int resultIndex = Array.IndexOf(dataTable.Rows[Convert.ToInt32(excelDataNames[1])].ItemArray, excelDataNames[4]);
            for (int index = 0; index < dataTable.Rows.Count - 1 - Convert.ToInt32(excelDataNames[1]); index++)
            {
                if (dataTable.Rows[index + 1 + Convert.ToInt32(excelDataNames[1])].ItemArray[resultIndex].ToString().ToUpper().Contains("PASS"))
                    passCount++;
                else
                    failCount++;
            }
            var currentDataName = ComboBoxEx.GetEnumName<eDataName>(otherConfiguration.DataName);
            string dateTimeString = string.Empty;
            switch (currentDataName)
            {
                case eDataName.Convention:
                    dateTimeString = dataTable.Rows[Convert.ToInt32(excelDataNames[1]) + 1].ItemArray[dataIndex].ToString();
                    break;
                case eDataName.Special:
                    dateTimeString = Convert.ToDateTime(dataTable.Rows[Convert.ToInt32(excelDataNames[1]) + 1].ItemArray[dataIndex]).ToString("yyyy-MM-dd");
                    break;
                default: throw new InvalidOperationException("指定类型无效");
            }
            productInfos = new ProductInfo()
            {
                DateTime = dateTimeString,
                Name = Convert.ToString(dataTable.Rows[Convert.ToInt32(excelDataNames[1]) + 1].ItemArray[numIndex]).ToUpper(),
                PassCount = passCount,
                FailCount = failCount,
                TotalCount = passCount + failCount
            };
        }
        catch (Exception ex)
        {
            WriteLog($"异常错误:{ex.Message}");
            productInfos = null;
        }
    });
    t0.Wait();
    return productInfos;
}

2、读取Excel表格内容程序:

private OleDbConnection connection;
public DataSet OpenExcel()
{
    try
    {
        DataSet dataSet = new DataSet();
        Task.Factory.StartNew(() =>
        {
            string connectionString = string.Empty;
            if (excelFileSuffix == ".xls")
            {
                 connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + excelFileName + ";Extended Properties=\"Excel 8.0;HDR=NO;IMEX=1\"";
            }
            else
            {
                connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + excelFileName + ";Extended Properties=\"Excel 12.0;HDR=NO;IMEX=1\"";
            }
            string sqlSelect = $"SELECT * FROM [{excelSheetName}$]";
            connection = new OleDbConnection(connectionString);
            OleDbCommand command = new OleDbCommand(sqlSelect, connection);
            OleDbDataAdapter adapter = new OleDbDataAdapter(command);
            connection.Open();
            adapter.Fill(dataSet);
        }).Wait();
        if (dataSet == null || dataSet.Tables.Count <= 0) return null;
        return dataSet;
    }
    catch (Exception ex)
    {
        throw new Exception($"Excel表打开失败!错误信息:{ex.Message}");
    }
}

四、选择文件、选择文件夹

1、选择文件:使用OpenFileDialog类库(System.Windows.Forms.OpenFileDialog)

using(OpenFileDialog dialog = new OpenFileDialog)
{
    dialog.Multiselect = true;
    dialog.Title = @"请选择文件夹”;
    dialog.Filter = @"Excel(*.xls)|*.xls|Excel(*.xlsx)|*.xlsx";
    if(dialog.ShowDialog() == DialogResult.OK)
    {
        string fileName = dialog.FileName;
    }
}

①Multiselect:该值确定是否可以选择多个文件;

②Filter:赋值为一字符串,用于过滤文件类型;如字符串“Excel(*.xls)|*.xls|Excel(*.xlsx)|*.xlsx” 表示的是:‘ |’分割的两个,一个是注释,一个是真的Filter,显示出来的是注释。

  • 如果要一次显示多种类型的文件,用分号分开。如:dialog.Filter = @"图片文件(*.jpg,*.gif,*.bmp)|*.jpg;*.gif;*.bmp";

  • 如果要分开显示多种类型的文件,用” | “隔开。如:dialog.Filter = @"Excel(*.xls)|*.xls|Excel(*.xlsx)|*.xlsx";

2、选择单个文件夹:使用FolderBrowserDialog类库(System.Windows.Forms.FolderBrowserDialog)

using (FolderBrowserDialog dialog = new FolderBrowserDialog())
{
    if (!string.IsNullOrEmpty(txtPathFile2.Text))
        dialog.SelectedPath = txtPathFile2.Text;
    dialog.Description = @"请选择加载后数据文档路径:";
    if (dialog.ShowDialog() == DialogResult.OK)
    {
        txtPathFile2.Text = dialog.SelectedPath;//显示选择文件夹的完成路径
    }
}

结果为:

3、选择多个文件夹:使用CommonOpenFileDialog类库(Microsoft.WindowsAPICodePack.Dialogs.CommonOpenFileDialog)

步骤:右键项目 -> 管理NuGet程序包 -> 在浏览选项卡中填写 WindowsAPICodePack-Shell 并设置为所需的包 -> 创建对话框

using (var dialog = new CommonOpenFileDialog())
{
    dialog.IsFolderPicker = true;//表示所选为文件夹模式而不是文件模式
    dialog.Multiselect = true;//表示可以选择多个文件夹
    if (dialog.ShowDialog() == CommonFileDialogResult.Ok)
    {
        var dataPath = dialog.FileNames;//所选所有文件夹的路径
        foreach (var dataFile in dataPath)
        {
            txtPathFile1.Text = dataFile;//显示所选第一个文件夹的路径
            return;
        }
    }
}

结果为:

五、DataSet的属性和方法

①属性

  • CaseSensitive:获取或设置一个值,该值指示DataTable中的字符串是否区分大小写。true:表示字符串区分大小写,false:表示字符串不区分大小写。默认为 false。
  • DefaultViewManager:获取DataSet中包含的数据的自定义视图,以允许使用自定义的DataViewManager进行筛选、搜索和导航。
  • DataSetName:获取或设置当前DataSet的名称。
  • EnforceConstraints:获取或设置一个值,该值指示是否在尝试任何更新操作时遵循约束规则。true:强制执行规则,否则为false,默认为 false。
  • ExtendedProperties:获取与DataSet相关联的自定义的用户信息的集合。
  • HasErrors:获取一个值,该值指示在DataTable中的任何DataSet对象是否存在错误。
  • IsInitialized:获取一个值,该值指示DataSet是否初始化。
  • Locale:获取或设置用来比较字符串表中的区域设置信息。
  • Namespace:获取或设置DataSet的命名空间。
  • Prefix:获取或设置XML前缀,该前缀是DataSet的命名空间的别名。
  • Relatios:获取关系链接表,并允许导航从父表到子表的集合。
  • RemotingFormat:获取或设置远程处理期间使用的确定的序列化DataSet。
  • SchemaSerializationMode:获取或设置SchemaSerializationMode模式的DataSet。
  • Site:获取或设置ISite的DataSet。
  • Tables:获取包含在DataSet中的表的集合。

②方法

  • BeginInit():开始初始化在窗体上使用或由另一个组件使用DataSet。初始化发生在运行时。
  • Clear():清除DataSet的所有表中删除所有行的任何数据。
  • Clone():将复制DataSet的结构,包括所有DataTable架构、关系和约束。不复制任何数据。
  • Copy():复制该DataSet的结构和数据。
  • DetermineSchemaSerializationMode(SerializationInfo info, StreamingContext context):确定DataSet的SchemaSerializationMode模式。
  • DetermineSchemaSerializationMode(XmlReader reader):确定DataSet的SchemaSerializationMode模式。
  • EndInit():结束在窗体上使用或由另一个组件使用的DataSet的初始化。初始化发生在运行时。
  • GetChanges():获取DataSet的副本,该副本包含自加载后或自上一次调用AcceptChanges()后对数据集做的所有更改。
  • GetChanges(DataRowState rowStates):获取由DataRowStatus筛选的DataSet副本,该副本包含自加载后或自上一次调用AcceptChanges()后对数据集做的所有更改。
  • GetSerializationData(SerializationInfo info, StreamingContext context):反序列化的二进制文件或XML流中的表数据。
  • GetObjectData(SerializationInfo info, StreamingContext context):使用序列化DataSet所需的数据填充序列化对象。
  • GetXml():返回存储在DataSet中的数据的XML表示形式。
  • GetXmlSchema():返回存储在DataSet中的数据的XML表示形式的XML架构。
  • GetSchemaSerializable():返回一个可序列化 System.Xml.Schema.XMLSchema 实例。
  • GetDataSetSchema(XmlSchemaSet schemaSet):获得一份 System.Xml.Schema.XmlSchemaSet 作为数据集。
  • HasChanges():获取一个值,该值指示是否 DataSet 已经更改,包括新的、 已删除,或已修改的行。
  • HasChanges(DataRowState rowStates):获取一个值,该值指示是否 DataSet 已经通过 DataRowState 筛选更改,包括新的、 已删除,或已修改的行。
  • InferXmlSchema(XmlReader reader, string[] nsArray):将指定 XmlReader 中的 XML 架构应用到 DataSet。
  • InferXmlSchema(Stream stream, string[] nsArray):将指定 Stream  中的 XML 架构应用到 DataSet。
  • InferXmlSchema(TextReader reader, string[] nsArray):将指定 TextReader 中的 XML 架构应用到 DataSet。
  • InferXmlSchema(string fileName, string[] nsArray):将指定文件中的 XML 架构应用到 DataSet。
  • InitializeDerivedDataSet():反序列化的所有表数据从二进制文件或XML流的数据集。
  • IsBinarySerialized(SerializationInfo info, StreamingContext context):检查DataSet序列化表示形式的格式。
  • Merge(DataSet dataSet):将指定的DataSet和架构合并到当前DataSet中。
  • Merge(DataSet dataSet, bool preserveChanges):将指定的DataSet和架构合并到当前DataSet中,在此过程中,根据给定的参数保留或放弃 DataSet 中的任何更改。
  • Merge(DataSet dataSet, bool preserveChanges, MissingSchemaAction missingSchemaAction):将指定的DataSet和架构合并到当前DataSet中,在此过程中,根据给定的参数保留或放弃在当前 DataSet中的更改并处理不兼容的架构。
  • Merge(DataTable table):将指定的 DataTable 和架构合并到当前DataSet中。
  • Merge(DataTable table, bool preserveChanges, MissingSchemaAction missingSchemaAction):将指定的 DataTable 和架构合并到当前DataSet中,在此过程中,根据给定的参数保留或放弃在当前 DataSet中的更改并处理不兼容的架构。
  • Merge(DataRow[] rows):将DataRow对象数组合并到当前 DataSet 中。
  • Merge( DataRow[] rows, bool preserveChanges, MissingSchemaAction missingSchemaAction):将DataRow对象数组合并到当前 DataSet 中,在此过程中,根据给定的参数保留或放弃在当前 DataSet中的更改并处理不兼容的架构。
  • OnPropertyChanging(PropertyChangedEventArgs pcevent):引发 DataSet.OnPropertyChanging(PropertyChangedEventArgs) 事件。
  • OnRemoveTable(DataTable table):当从DataTable中移除 DataSet时发生。
  • OnRemoveRelation(DataRelation relation):当从DataRelation中一处DataTable时发生。
  • RaisePropertyChanging(string name):将通知发送指定 DataSet 即将更改的属性。
  • RejectChanges():回滚自创建 DataSet 以来或上次调用 AcceptChanges() 所做的左右更改。
  • Reset():清除所有表并从 DataSet 中删除所有关系、 外部约束和表。子类应重写 Reset, 将 DataSet 还原到其原始状态。
  • ReadXmlSchema(XmlReader reader):从指定 XmlReader 中将 XML 架构读取到 DataSet。
  • ReadXmlSchema(Stream stream):从指定 Stream 中将 XML 架构读取到 DataSet。
  • ReadXmlSchema(TextReader reader):从指定 TextReader 中将 XML 架构读取到 DataSet。
  • ReadXmlSchema(string fileName):从指定文件将 XML 架构读取到 DataSet。
  • ReadXml(XmlReader reader):使用指定的 XmlReader 将 XML 架构和数据读入DataSet。
  • ReadXml(Stream stream):使用指定的 Stream  将 XML 架构和数据读入DataSet。
  • ReadXml(TextReader reader):使用指定的 TextReader 将 XML 架构和数据读入DataSet。
  • ReadXml(string fileName):使用指定的文件将 XML 架构和数据读入DataSet。
  • ReadXml(XmlReader reader, XmlReadMode mode):使用指定的 XmlReader 和 XmlReadMode 模式将 XML 架构和数据读入DataSet。
  • ReadXml(Stream stream, XmlReadMode mode):使用指定的 Stream 和 XmlReadMode 模式将 XML 架构和数据读入DataSet。
  • ReadXml(TextReader stream, XmlReadMode mode):使用指定的 TextReader 和 XmlReadMode 模式将 XML 架构和数据读入DataSet。
  • ReadXml(string fileName, XmlReadMode mode):使用指定的文件和 XmlReadMode 模式将 XML 架构和数据读入DataSet。
  • ReadXmlSerializable(XmlReader reader):将忽略属性,并返回一个空数据集。
  • WriteXmlSchema(Stream stream):将 DataSet 结构作为 XML 架构写入指定的 Stream 对象。
  • WriteXmlSchema(Stream stream, Converter<Type, string> multipleTargetConverter):将 DataSet 结构作为 XML 架构写入指定的 Stream 对象。
  • WriteXmlSchema(string fileName):将 DataSet 结构作为 XML 架构写入文件。
  • WriteXmlSchema(string fileName, Converter<Type, string> multipleTargetConverter):将 DataSet 结构作为 XML 架构写入文件。
  • WriteXmlSchema(TextWriter writer):将 DataSet 结构作为 XML 架构写入指定的 TextWriter 对象。
  • WriteXmlSchema(TextWriter writer, Converter<Type, string> multipleTargetConverter):将 DataSet 结构作为 XML 架构写入指定的 TextWriter 对象。
  • WriteXmlSchema(XmlWriter writer):将 DataSet 结构作为 XML 架构写入指定的 XmlWriter  对象。
  • WriteXmlSchema(XmlWriter writer, Converter<Type, string> multipleTargetConverter):将 DataSet 结构作为 XML 架构写入指定的 XmlWriter 对象。
  • WriteXml(Stream stream):使用指定的 Stream 将当前数据写入 DataSet。
  • WriteXml(TextWriter writer):使用指定的 TextWriter 将当前数据写入 DataSet。
  • WriteXml(XmlWriter writer):使用指定的 XmlWriter 将当前数据写入 DataSet。
  • WriteXml(string fileName):使用指定的文件将当前数据写入 DataSet。
  • WriteXml(Stream stream, XmlWriteMode mode):使用指定的 Stream 和 XmlWriteMode 写入 DataSet 的当前数据和架构(可选)。编写该架构,请设置mode参数为:WriteSchema。
  • WriteXml(TextWriter writer, XmlWriteMode mode):使用指定的 TextWriter 和 XmlWriteMode 写入 DataSet 的当前数据和架构(可选)。编写该架构,请设置mode参数为:WriteSchema。
  • WriteXml(XmlWriter writer, XmlWriteMode mode):使用指定的 XmlWriter 和 XmlWriteMode 写入 DataSet 的当前数据和架构(可选)。编写该架构,请设置mode参数为:WriteSchema。
  • WriteXml(string fileName, XmlWriteMode mode):使用指定的 XmlWriteMode 将 DataSet 当前的数据和架构(可选)写入指定的文件中。编写该架构,请设置mode参数为:WriteSchema。
  • ShouldSerializeRelations():获取一个值,该值指示是否保持Relations属性。
  • ShouldSerializeTables():获取一个值,该值指示是否保持Tables属性。
posted @ 2023-10-30 10:10  ycx-x  Views(187)  Comments(0Edit  收藏  举报