c# - 初学者数据库最佳实践

标签 c# .net database

所以,我是一个相当新的程序员,正在攻读 Comp Sci 本科学位,工作经验很少。在为我的项目寻找实习类型的工作时,我注意到我从几位教授那里听到的——“使用数据库占所有现代计算机科学工作的 90%”——看起来确实如此。但是,直到第 3 年我的类(class)才真正有任何关于数据库的类(class),所以我正在努力至少在这段时间内自己学习一些东西。

对于像我这样的人,我在 SO 和互联网上看到的很少。似乎有大量关于如何在数据库中读取和写入数据的机制的教程,但关于相关最佳实践的教程却很少。为了证明我在说什么,并帮助解决我的实际问题,这里有什么可以 easily be found on the internet :

public static void Main ()
{
    using (var conn = new OdbcConnection())
    {
        var command = new OdbcCommand();
        command.Connection = conn;
        command.CommandText = "SELECT * FROM Customer WHERE id = 1";
        var dbAdapter = new OdbcDataAdapter();
        dbAdapter.SelectCommand = command;
        var results = new DataTable();
        dbAdapter.Fill(results);
    }

    // then you would do something like
    string customerName = (string) results.Rows[0]["name"]; 
}

等等。这很容易理解,但显然充满了问题。我从这样的代码开始,很快就开始说“好吧,到处都是 SQL 似乎很愚蠢,我应该把所有这些都放在一个常量文件中。”然后我意识到到处都是这些相同的代码行并将所有这些带有连接对象等的东西放在一个方法中是很愚蠢的:

public DataTable GetTableFromDB (string sql)
{
    // code similar to first sample
}    

string getCustomerSql = String.Format(Constants.SelectAllFromCustomer, customerId);
DataTable customer = GetTableFromDB(getCustomerSql);
string customerName = (string) customer.Rows[0]["name"];

这似乎是一个很大的进步。现在可以非常容易地从 OdbcConnection 更改为 SQLiteConnection。但是最后一行,访问数据,看起来仍然很尴尬;并且更改字段名称仍然很痛苦(例如从“名称”更改为“CustName”或其他名称)。我开始阅读 using typed Data sets or custom business objects .我仍然对所有术语感到困惑,但决定 to look into it anyway.我认为在我真正了解正在发生的事情以及原因之前,依靠 Shiny 的数据库向导为我做所有这些事情(就像在链接的文章中)是愚蠢的。所以我自己试了一下,开始得到类似的东西:

public class Customer
{
    public string Name {get; set;}
    public int Id {get; set;}

    public void Populate ()
    {
        string getCustomerSql = String.Format(Constants.SelectAllFromCustomer, this.Id);
        DataTable customer = GetTableFromDB(getCustomerSql);
        this.Name = (string) customer.Rows[0]["name"]; 
    }

    public static IEnumerable<Customer> GetAll()
    {
        foreach ( ... ) { 
            // blah blah
            yield return customer;
        }
    }
}

隐藏丑陋的表格内容并提供一些强类型,允许外部代码只做类似的事情

var customer = new Customer(custId);
customer.Populate();
string customerName = customer.Name;

这真是太好了。如果 Customer 表发生变化,代码的变化只需要发生在一个地方:在 Customer 类中。

所以,在所有这些杂乱无章的结尾,我的问题是这个。我对数据库代码的缓慢改进是否朝着正确的方向发展?接下来我该去哪里?这种风格非常适合小型数据库,但是当有大量不同的表时,为每个表写出所有这些类将是一件痛苦的事情。我听说过可以为您生成此类代码的软件,但我仍然对 DAL/ORM/LINQ2SQL/等行话感到困惑,而且那些庞大的软件有点让人不知所措。我正在寻找一些好的但不太复杂的资源,这些资源可以为我指明正确的方向。关于这个主题,我所能找到的都是复杂的文章,这些文章让我难以理解,或者只是向您展示如何在 Visual Studio 中使用点击向导等。另请注意,我正在寻找有关在代码中使用数据库的信息,而不是有关数据库设计/规范化的信息……那里有很多很好的 Material 。

感谢阅读这面巨大的文字墙。

最佳答案

确实是个好问题,您肯定是在正确的轨道上!

我自己是一名计算机工程师,数据库以及如何编写代码与数据库交互也从来不是我大学学位的重要组成部分,而且我确实负责工作中的所有数据库代码。

这是我的经验,在一个项目中使用 90 年代初的遗留技术,在另一个项目中使用 C# 和 WPF 等现代技术。

我会尽我所能解释术语,但我自己肯定不是专家。

表、对象和映射天哪!

数据库包含表格,但表格到底是什么?它只是与其他平面数据相关的平面数据,如果您深入研究并开始抓取东西,它很快就会变得一团糟!字符串将无处不在,SQL 语句重复,记录加载两次,等等。因此,将每个表记录(或表记录的集合,取决于它们的关系)表示为单个对象通常是一个很好的做法,通常称为作为一个模型。这有助于封装数据并提供维护和更新其状态的功能。

在您的帖子中,您的客户类将充当模型!所以您已经意识到了这一好处。

现在有多种工具/框架(LINQ2SQL、dotConnect、Mindscape LightSpeed)可以为您编写所有模型代码。最后,他们将对象映射到关系表或 O/R 映射,因为他们引用它。

正如预期的那样,当您的数据库发生变化时,您的 O/R 映射也会发生变化。就像您谈到的那样,如果您的客户发生变化,您必须在一个地方修复它,这又是为什么我们把东西放在类中。在我的遗留项目中,更新模型消耗了大量时间,因为它们太多了,而在我的新项目中,只需点击几下,但最终结果是一样的。

谁应该知道什么?

在我的两个项目中,对象与表格的交互方式有两种不同的方式。

在一些阵营中,模型应该知道关于他们的表的一切,如何保存自己,对连接/ session 有直接的共享访问,并且可以执行像 Customer.Delete() 这样的操作Customer.Save() 全部靠自己。

其他阵营,把读、写、删、逻辑放在一个管理类中。例如, MySessionManager.Save( myCustomer )。这种方法的优点是能够轻松实现对对象的更改跟踪,并确保所有对象都引用相同的基础表记录。然而,实现它比前面提到的本地化类/表逻辑的方法更复杂。

结论

您走在正确的轨道上,在我看来,与数据库交互是非常有益的。我还记得自己刚开始做研究时的头晕目眩。

我建议进行一些试验,开始一个小项目,比如一个简单的发票系统,然后尝试自己编写模型。之后尝试另一个小项目并尝试利用数据库 O/R 映射工具并查看差异。

关于c# - 初学者数据库最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3313803/

相关文章:

c# - C# 编译器如何检测 COM 类型?

c# - 保存位图时发生 GDI+ 异常中的一般错误

c# - 大型 HTTPResponseMessage 导致 .NET Core 服务器进程内存不足

php - 如何在 Laravel 中使用多个数据库

mysql - 自然连接给出两个关系的笛卡尔积

mysql - Oracle 与 MySQL - 聚合函数

c# - XmlElement 继承

c# - 第一页显示最后 10 行,下一页显示最后 10 行

c# - 导致重复 ID 问题的分离实体

c# - 如何使用 VS Code 调试多项目?