Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#与数据库代码简化_C#_Database_Performance - Fatal编程技术网

C#与数据库代码简化

C#与数据库代码简化,c#,database,performance,C#,Database,Performance,我正在从事一个以Oracle数据库为中心的项目(尽管老实说,我并不认为这很重要),我发现自己有大量重复的代码,特别是例外。到目前为止,我所看到的最好的方法是从这个问题开始,它建议使用代理。在我尝试在我的项目中实现它之前,这看起来是一个完美的解决方案。我发现我有一个案例是不实际的 让我描述一下我的程序。我有两段代码处理数据库操作。我的想法是调用一个返回DataTable的函数,名为LoadDataTable()。然后,我有一个函数,用于将列表中的项插入到表中 private void AddToL

我正在从事一个以Oracle数据库为中心的项目(尽管老实说,我并不认为这很重要),我发现自己有大量重复的代码,特别是例外。到目前为止,我所看到的最好的方法是从这个问题开始,它建议使用代理。在我尝试在我的项目中实现它之前,这看起来是一个完美的解决方案。我发现我有一个案例是不实际的

让我描述一下我的程序。我有两段代码处理数据库操作。我的想法是调用一个返回DataTable的函数,名为LoadDataTable()。然后,我有一个函数,用于将列表中的项插入到表中

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));