C#与数据库代码简化
我正在从事一个以Oracle数据库为中心的项目(尽管老实说,我并不认为这很重要),我发现自己有大量重复的代码,特别是例外。到目前为止,我所看到的最好的方法是从这个问题开始,它建议使用代理。在我尝试在我的项目中实现它之前,这看起来是一个完美的解决方案。我发现我有一个案例是不实际的 让我描述一下我的程序。我有两段代码处理数据库操作。我的想法是调用一个返回DataTable的函数,名为LoadDataTable()。然后,我有一个函数,用于将列表中的项插入到表中C#与数据库代码简化,c#,database,performance,C#,Database,Performance,我正在从事一个以Oracle数据库为中心的项目(尽管老实说,我并不认为这很重要),我发现自己有大量重复的代码,特别是例外。到目前为止,我所看到的最好的方法是从这个问题开始,它建议使用代理。在我尝试在我的项目中实现它之前,这看起来是一个完美的解决方案。我发现我有一个案例是不实际的 让我描述一下我的程序。我有两段代码处理数据库操作。我的想法是调用一个返回DataTable的函数,名为LoadDataTable()。然后,我有一个函数,用于将列表中的项插入到表中 private void AddToL
private void AddToList(List<string> itemList) {
try {
using (OracleConnection connection = new OracleConnection(connectionString)) {
connection.Open();
foreach (string item in itemList) {
using (OracleCommand command = new OracleCommand()) {
command.Connection = connection;
//Insert operation here
//......
command.ExecuteNonQuery();
}
}
} catch (OracleException ex) {
string messageboxtitle = "Database Exception";
switch (ex.Number) {
case 00001:
MessageBox.Show("Constraint Violation Error", messageboxtitle, MessageBoxButtons.OK);
break;
case 12154:
MessageBox.Show(string.Format("Connection Error: {0}", ex.Message), messageboxtitle);
break;
default:
MessageBox.Show(ex.ToString());
break;
}
}
}
private DataTable LoadDataTable() {
DataTable dataTable = new DataTable();
try {
using (OracleConnection connection = new OracleConnection(connectionString)) {
connection.Open();
using (OracleCommand command = new OracleCommand()) {
command.Connection = connection;
command.CommandText = sql;
command.CommandType = CommandType.Text;
using (OracleDataAdapter oda = new OracleDataAdapter(command)) {
oda.Fill(dataTable);
}
}
}
} catch (OracleException ex) {
string messageboxtitle = "Database Exception";
switch (ex.Number) {
case 12154:
MessageBox.Show(string.Format("Connection Error: {0}", ex.Message), messageboxtitle); //Duplicate Exception
break;
default:
MessageBox.Show(ex.ToString());
break;
}
}
return dataTable;
}
传递不同参数的一种常用模式是将它们传递给构造函数。优点是构造函数不是接口的一部分。但是,它要求您使用对象而不是代理
public interface IDatabaseOperation
{
void Execute();
}
public class LoadListDatabaseOperation : IDatabaseOperation
{
private List<string> _itemList;
public LoadListDatabaseOperation(List<string> itemList)
{
_itemList = itemList;
}
public void Execute()
{
...
// Fill the list here
...
}
}
公共接口IDatabaseOperation
{
void Execute();
}
公共类LoadListDatabaseOperation:IDatabaseOperation
{
私有列表_itemList;
公共LoadListDatabaseOperation(列表项列表)
{
_itemList=itemList;
}
public void Execute()
{
...
//在这里填写清单
...
}
}
传递对象的成本稍高,但也有一些优点,比如能够创建具有不同专门化程度的操作层次结构。您可能有泛型基操作和为特定类型专门化的派生操作。您还可以对标量返回值等使用属性。我建议您使用micro ORM,例如它支持Oracle。如果代码可以自动生成,为什么还要编写这些代码呢?如果您想编写自己的数据访问层,我建议您为类创建CRUD方法,例如
public bool Insert(Person p)
{...}
您还可以研究使用通用方法来实现这一点,例如:
public bool Insert<T>(T item)
{...}
public bool Insert(T项)
{...}
请记住,委托从父方法的主体中捕获变量。这也被称为a。因此,委托通常不需要有参数列表
var itemList = new List<string>();
PerformDatabaseOperation(
() => {
...
itemList.Add(...);
...
}
);
var itemList=新列表();
PerformDatabase操作(
() => {
...
添加(…);
...
}
);
更新 你可以这样称呼它:
List<string> itemList = new List<string>();
PerformDatabaseOperation(() => AddToList(itemList));
List itemList=new List();
PerformDatabaseOperation(()=>AddToList(itemList));
诀窍是将lambda表达式传递给没有参数的
PerformDatabaseOperation
(空括号()
);另外,PerformDatabaseOperation
具有否itemList
参数。lambda表达式的主体使用在调用PerformDatabaseOperation
之前声明和初始化的itemList
。C#编译器魔法完成了其余的工作。天哪,你的代码太像java了,让我头疼。你到底为什么要做埃及大括号??请使用var
关键字<代码>var itemList=新列表()代码>为什么您的房地产丢失??你在说什么?你的代码太可怕了。C#不做埃及牙套。这属于像java这样的蹩脚语言。而var
关键字是为了可读性。有些东西你真的不认为我猜。我有一些<代码>观察代码< <代码> >在我的一个ViewModels中。您是否愿意选择observateCollection ViewModels=newobservateCollection()
或使用var
关键字?@Rakshasas因为var关键字总是与赋值在同一行,所以模糊性不是真正的问题;尤其是当你使用“new”关键字时。不过,这并不像HighCore所认为的那样是个大问题。-1这鼓励了类似java的黑客使用接口来模仿C#的委托。坏主意。@HighCore:这也叫做命令模式,一种非常强大的模式。在这种情况下,也可以将其视为策略模式,因为注入了不同的数据库访问策略。拥有更多的代码来实现相同的结果总是一个错误,这表明设计很差。委托是一种方式,更多的代码,好吧,但它也有优势,因为你可以创建命令的层次结构;e、 例如,您可能有一个基本列表加载命令,并从中派生专门的加载列表命令来执行一些过滤(例如使用Regex模式)。这种可能性是无穷的。这也可以通过代表来实现。以更干净的方式。我的观点仍然站得住脚。我觉得这很有趣,但这些片段在我的脑海里并没有完全融合在一起。我对委派的概念非常陌生,所以我想知道很多事情。在我的代码中,我删除了参数private delegate void DatabaseOperation()代码>。我很想知道您使用PerformDatabaseOperation
时如何准确调用AddToList。我想AddToList仍然会被编码为接受一个参数?我添加了一个使用AddToList
调用PerformDatabaseOperation
的示例。谢谢,我的理解有点偏差,我能够解决我的问题。
public bool Insert<T>(T item)
{...}
var itemList = new List<string>();
PerformDatabaseOperation(
() => {
...
itemList.Add(...);
...
}
);
List<string> itemList = new List<string>();
PerformDatabaseOperation(() => AddToList(itemList));