C# 使用数据集的更有效方法
作为更新过程的一部分,我在每个C# 使用数据集的更有效方法,c#,.net,winforms,refactoring,dataset,C#,.net,Winforms,Refactoring,Dataset,作为更新过程的一部分,我在每个表单上重复了以下代码。当页面加载BLL时,返回一个数据集,例如 _personInfo = ConnectBLL.BLL.Person.GetPerson(personID); 我将该数据集存储在表单级别变量中,然后在验证/更新过程中使用该变量检查更改。我一次将一行传递给一个函数,该函数接受控件中的值,并将其与数据集中相应的列值进行比较。如果发现不同,则将该列=设置为新值,并将该名称添加到更改内容的列表中 // Load Person info u
表单上重复了以下代码。当页面加载BLL
时,返回一个数据集,例如
_personInfo = ConnectBLL.BLL.Person.GetPerson(personID);
我将该数据集
存储在表单
级别变量中,然后在验证/更新过程中使用该变量检查更改。我一次将一行传递给一个函数,该函数接受控件中的值,并将其与数据集中相应的列值进行比较。如果发现不同,则将该列=设置为新值,并将该名称添加到更改内容的列表中
// Load Person info
using (var tmpPersonDT = tmpPersonDS.Tables[0])
{
if (tmpPersonDT.Rows.Count > 0)
{
foreach (DataRow row in tmpPersonDT.Rows)
{
CheckPersonData(row);
}
}
}
// Snippet of the CheckPersonData() that is being called....
if (!object.Equals(row["ResidencyCountyID"], lkuResidenceCounty.EditValue))
{
row["ResidencyCountyID"] = lkuResidenceCounty.EditValue;
_whatChanged.Add("ResidencyCounty");
}
if (!object.Equals(row["ResponsibilityCountyID"], lkuResponsibleCounty.EditValue))
{
row["ResponsibilityCountyID"] = lkuResponsibleCounty.EditValue;
_whatChanged.Add("ResponsibilityCounty");
}
if (!object.Equals(row["HispanicOriginFlag"], chkHispanic.EditValue))
{
row["HispanicOriginFlag"] = chkHispanic.EditValue;
_whatChanged.Add("HispanicOriginFlag");
}
if (!object.Equals(row["CitizenFlag"], chkCitizen.EditValue))
{
row["CitizenFlag"] = chkCitizen.EditValue;
_whatChanged.Add("CitizenFlag");
}
if (!object.Equals(row["VeteranFlag"], chkVeteran.EditValue))
{
row["VeteranFlag"] = chkVeteran.EditValue;
_whatChanged.Add("VeteranFlag");
}
我想得到的答案是,这真的是最有效的解决方法吗?
如果没有别的,我想创建一个函数来进行比较,而不是重复30次(每种形式各不相同),但我不太明白这一点。我想也许我可以使用row[].ItemArray,但它只有值。我必须提前知道物品的顺序,并保证它们不会改变
在CRUD应用程序中使用数据集/数据表时,我是否遗漏了一些明显的东西
我只是,现在,需要一些关于如何在上面使用它的指导。任何人都可以指向我的链接将不胜感激。如果你能举个例子就更好了
像这样使用数据行有什么缺点吗?看起来您正在做大量的手工劳动,通过将控件直接数据绑定到数据集/表可以减轻这些劳动。数据绑定将数据源(本例中为数据集/表)与UI垂直连接在一起。当UI中的值更改时,它将更新数据源
数据绑定是一个值得研究和测试的大课题。将数据绑定到DataTable/Set有一些问题(行更改直到当前行更改才提交,这对于一次只处理一行的情况来说很烦人,但是有一些解决方法)
改写:
要考虑的另一件事是使用业务对象来表示集合/表中的数据。ORM(对象关系映射器)可以为您处理这个问题,但它们是大型且功能强大的框架,不容易掌握。它与在UI层处理数据集/表完全不同,更适用于面向对象编程。数据集和表非常适合处理表格数据,但它们不适合处理实体。例如,您可以对具有IsHispanic和IsCitizen rahtner等属性的Person对象实例进行操作,而不是对表中的单元格进行操作(不再是*myPersonTable[0][“HispanicOriginFlag”]…)
进一步:与您的问题无关,但与围绕ADO.NET的CRUD操作相关:熟悉DataTable/DataSet中内置的状态跟踪是值得的。ADO.NET中有很多内置功能,可以帮助这些应用程序轻松地粘合在一起,这将清理大量代码,如您所示
和往常一样,RAD工具有一个折衷办法,即放弃对生产力的控制——但是在不理解它们的情况下将它们写下来,这就保证了您将像您所展示的那样花上一天的时间来编写代码
更进一步:要在我之前的基础上进一步构建,当您发现能够将Visual Studio的数据集生成器与内置的数据表行状态跟踪相结合,并更改数据集跟踪时,可以很容易地在短时间内编写完整的CRUD系统
下面是一些相关步骤的简要介绍:
建立数据库模式
在Visual Studio中,向项目添加新的数据集项
查找服务器资源管理器(在“视图”下)
将SQL Server添加为数据连接
将表/存储过程/视图拖动到数据集的设计器中
右键单击VisualStudio为您生成的“TableAdapter”;转到配置
为数据集配置CRUD命令(Select、Insert、Update、Delete命令)
这样就创建了一个强类型数据集。数据集将包含一个以用于生成数据集的表/视图/存储过程命名的DataTable属性。该表属性将包含强类型行,这允许您作为属性而不是对象数组中的非类型项访问该行中的单元格
因此,如果您已经生成了一个名为MyDbTables的新数据集,以及一个名为tblCustomer的表,该表包含一些列,如CustomerId、Name等。。。然后您可以像这样使用它:
这是一个综合了多种示例的例子,展示了CRUD工作中使用的一些常用方法——查看这些方法,特别是TableAdapter类
public void MyDtDemo()
{
// A TableAdapter is used to perform the CRUD operations to sync the DataSet/Table and Database
var myTa = new ClassLibrary4.MyDbTablesTableAdapters.tblCustomersTableAdapter();
var myDataSet = new MyDbTables();
// 'Fill' will execute the TableAdapter's SELECT command to populate the DataTable
myTa.Fill(myDataSet.tblCustomers);
// Create a new Customer, and add him to the tblCustomers table
var newCustomer = myDataSet.tblCustomers.NewtblCustomersRow();
newCustomer.Name = "John Smith";
myDataSet.tblCustomers.AddtblCustomersRow(newCustomer);
// Show the pending changes in the DataTable
var myTableChanges = myDataSet.tblCustomers.GetChanges();
// Or get the changes by change-state
var myNewCustomers = myDataSet.tblCustomers.GetChanges(System.Data.DataRowState.Added);
// Cancel the changes (if you don't want to commit them)
myDataSet.tblCustomers.RejectChanges();
// - Or Commit them back to the Database using the TableAdapter again
myTa.Update(myDataSet);
}
另外,请注意数据集和数据表的RejectChanges()和AcceptChanges()方法。它们本质上告诉您的数据集它没有任何更改(通过拒绝所有更改或“提交”所有更改),但请注意,调用AcceptChanges()然后尝试执行更新不会产生任何效果——数据集已失去对任何更改的跟踪,并假定它是数据库的准确反映
甚至更多!假设您按照我的步骤创建了强类型数据集/表/行,下面是示例的修改版本,其中显示了一些行状态跟踪功能
public void MyDtDemo()
{
// A TableAdapter is used to perform the CRUD operations to sync the DataSet/Table and Database
var myTa = new ClassLibrary4.MyDbTablesTableAdapters.tblCustomersTableAdapter();
var myDataSet = new MyDbTables();
// 'Fill' will execute the TableAdapter's SELECT command to populate the DataTable
myTa.Fill(myDataSet.tblCustomers);
// Create a new Customer, and add him to the tblCustomers table
var newCustomer = myDataSet.tblCustomers.NewtblCustomersRow();
newCustomer.Name = "John Smith";
myDataSet.tblCustomers.AddtblCustomersRow(newCustomer);
// Show the pending changes in the DataTable
var myTableChanges = myDataSet.tblCustomers.GetChanges();
// Or get the changes by change-state
var myNewCustomers = myDataSet.tblCustomers.GetChanges(System.Data.DataRowState.Added);
// Cancel the changes (if you don't want to commit them)
myDataSet.tblCustomers.RejectChanges();
// - Or Commit them back to the Database using the TableAdapter again
myTa.Update(myDataSet);
}
public void CheckRows()
{
MyPersonDS tmpPersonDS=新的MyPersonDS();
//加载个人信息
使用(var tmpPersonDT=tmpPersonDS.PersonDT)
{
foreach(tmpPersonDT.Rows中的MyPersonRow行)
{
CheckPersonData(世界其他地区);
}
}
}
公共无效支票数据
DataRow _personInfo = ConnectBLL.BLL.Person.GetPerson(personID);
// _personInfo.RowState = DataRowState.Unchanged
_personInfo["columnName"] = "value";
_personInfo["columnName2"] = "value2";
_personInfo.EndEdit();
// _personInfo.RowState = DataRowState.Modified
var org = fRow["columnName", DataRowVersion.Original];
var new = fRow["columnName",DataRowVersion.Current];
fTable.ColumnChanged += new DataColumnChangeEventHandler(delegate(object sender, DataColumnChangeEventArgs e)
{
Console.WriteLine(e.Column.ColumnName);
}
);