Ref*_*din 4 .net c# refactoring dataset winforms
Form作为更新过程的一部分,我在每个代码上重复了以下代码.当页面加载BLL返回a时DataSet,比方说
_personInfo = ConnectBLL.BLL.Person.GetPerson(personID);
Run Code Online (Sandbox Code Playgroud)
我将它存储DataSet在一个Form级别变量中,然后我在验证/更新过程中使用它来检查更改.我一次传递一行(尽管永远不会超过一行)到Function一个控件中的值,并将其与其中相应的列值进行比较DataSet.如果它发现它不同,那么它将该列设置为新值,并将名称添加到List更改的内容中.
// 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");
}
Run Code Online (Sandbox Code Playgroud)
我想要得到的答案是,这真的是最有效的解决方法吗?
如果没有别的我想创建一个功能来进行比较,而不是重复30次(每个形式各不相同),但我不能完全弄明白.我想也许我可以使用row [].ItemArray但只有值.我必须提前知道这些物品的订单是什么,并且它们不会改变......
我是否遗漏了在CRUD应用程序中使用DataSets/DataTables的明显事项?
我现在需要一些关于如何在上面使用它的方向.任何人都可以指向我的链接将不胜感激.如果你能发布一个例子,那就更好了.
使用像这样的DataRows有什么缺点吗?
看起来你正在做大量的手工劳动,可以通过将控件直接数据绑定到DataSet/Table来缓解.数据绑定将您的数据源(在本例中为您的数据集/表)与您的UI联系在一起.当UI中的值发生变化时,它将更新数据源.
数据绑定是一个大话题,权证研究和测试.有一些关于数据绑定到DataTable/Set的问题(行更改在当前行更改之前不会被提交,这在您一次只处理一行的情况下很烦人 - 但是有解决方法).
Reworded: 要考虑的另一件事是使用业务对象来表示集/表中的数据.ORM(对象关系映射器)可以为您处理这个问题,但它们是庞大且功能强大的框架,不容易掌握.这与在UI层使用DataSet的/ Tables完全不同,并且更适用于面向对象的编程.DataSets和Tables非常适合处理表格数据,但它们不适合使用实体.例如,您将使用IsHispanic和IsCitizen rahtner 等属性来处理Person对象的实例,而不是基本上对照表中的单元格(不再是*myPersonTable [0] ["HispanicOriginFlag"] ....).
进一步:与您的问题无关,但与围绕ADO.NET的CRUD操作相关:熟悉DataTable/DataSet中内置的状态跟踪是值得的.ADO.NET中有很多内容可以帮助使这些应用程序易于粘合在一起,这样可以清理大量代码,就像你所展示的那样.
一如往常,RAD工具需要权衡放弃对生产力的控制 - 但是在不了解它们的情况下将它们写下来是可以保证您将花费时间编写像您所展示的代码.
更多:进一步构建我以前的内容进一步,当您发现将Visual Studio的DataSet生成器与DataTables的内置行状态跟踪以及DataSet的更改跟踪相结合时,可以非常轻松地编写完整的CRUD系统.很少的时间.
以下是对所涉及的一些步骤的快速破坏:
有了这个,你就创建了一个强类型数据集.DataSet将包含以用于生成DataSet的表/视图/存储过程命名的DataTable属性.该Table属性将包含强类型行,这使您可以将该行中的单元格作为属性而不是对象数组中的无类型项目进行访问.
因此,如果您已经生成了一个名为MyDbTables的新DataSet ,其中包含一个名为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);
}
Run Code Online (Sandbox Code Playgroud)
另外,请注意DataSet和DataTables的RejectChanges()和AcceptChanges()方法.它们实质上告诉您的数据集它没有任何更改(通过拒绝所有更改,或"提交"所有更改),但要注意调用AcceptChanges()然后尝试进行更新将不起作用 - DataSet已丢失跟踪任何更改并假设它是数据库的准确反映.
还有更多!这是一个重新设计的示例版本,显示了一些rowstate跟踪功能,假设您已按照我的步骤创建强类型DataSet/Tables/Rows
public void CheckRows()
{
MyPersonDS tmpPersonDS = new MyPersonDS();
// Load Person info
using (var tmpPersonDT = tmpPersonDS.PersonDT)
{
foreach (MyPersonRow row in tmpPersonDT.Rows)
{
CheckPersonData(row);
}
}
}
public void CheckPersonData(MyPersonRow row)
{
// If DataBinding is used, then show if the row is unchanged / modified / new...
System.Diagnostics.Debug.WriteLine("Row State: " + row.RowState.ToString());
System.Diagnostics.Debug.WriteLine("Row Changes:");
System.Diagnostics.Debug.WriteLine(BuildRowChangeSummary(row));
// If not DataBound then update the strongly-types Row properties
row.ResidencyCountyID = lkuResidencyCountyId.EditValue;
}
public string BuildRowChangeSummary(DataRow row)
{
System.Text.StringBuilder result = new System.Text.StringBuilder();
int rowColumnCount = row.Table.Columns.Count;
for (int index = 0; index < rowColumnCount; ++index)
{
result.Append(string.Format("Original value of {0}: {1}\r\n", row.Table.Columns[index].ColumnName, row[index, DataRowVersion.Original]));
result.Append(string.Format("Current value of {0}: {1}\r\n", row.Table.Columns[index].ColumnName, row[index, DataRowVersion.Current]));
if (index < rowColumnCount - 1) { result.Append("\r\n"); }
}
return result.ToString();
}
Run Code Online (Sandbox Code Playgroud)