使用 .NET 平台进行数据访问






4.62/5 (14投票s)
关于 ADO.NET 和 Entity Framework,您需要了解的内容
引言
在大多数编程语言中,访问数据都非常重要,因此 Microsoft 提供了一套重要的类,使开发人员能够访问多个数据库并处理数据。Microsoft 开发人员可以使用许多数据访问框架。在本文中,我们将只讨论两种场景
- ADO.NET
- 连接模式
- 断开模式
- Entity Framework(数据库方法)
这些框架都不是过时的,我们将通过一个实际的研讨会详细解释它们。
背景
本文可能对具有 C# 和 .NET 基础的初级开发人员有用。
Using the Code
通过本节,我们将解释如何访问 SQL Server 数据库。在每种数据访问场景中使用的工具是
- SQL SERVER 2012
- SQL Management studio 2012
- Visual Studio 2012
I. ADO.NET
ADO.NET 出现在 Microsoft .NET Framework 的第一个版本中,它提供了一种方法,帮助我们学习编程模型,然后能够处理 .NET 支持的几乎任何数据库。
例如,如果开发人员知道如何访问 SQL Server 数据库,那么他们就可以访问 Oracle 数据库或 MySQL 数据库,他们只需添加对适当提供程序的引用,因为编程模型是相同的。
- ADO.NET 是 ADO(Active X 数据对象)的托管版本
- OLEDB 访问:
System.Data.OleDb
- SQL Server 访问:
System.Data.SqlClient
- Oracle 访问:
System.Data.OracleClient
- ODBC 访问:
System.Data.Odbc
ADO.NET 包含许多组件
- .NET 数据提供程序
- NET Framework 数据提供程序是专门为数据操作以及快速、向前、只读访问数据而设计的组件。
Connection
对象提供到数据源的连接。Command
对象允许访问数据库命令以检索数据、修改数据、运行存储过程以及发送或检索参数信息。DataReader
提供来自数据源的高性能数据流,并用于连接模式场景。 - 最后,
DataAdapter
提供了DataSet
对象与数据源之间的桥梁。DataAdapter
使用Command
对象在数据源上执行 SQL 命令,以将数据加载到DataSet
中,并将DataSet
中所做的更改协调回数据源。
- NET Framework 数据提供程序是专门为数据操作以及快速、向前、只读访问数据而设计的组件。
- 数据集:简单来说,
DataSet
是内存中的数据库,它用于(请参阅断开模式部分)。
选择 DataReader(连接模式)还是 DataSet(断开模式)?
当您决定应用程序是否应使用 DataReader
或 DataSet
时,请考虑应用程序需要的功能类型。使用 DataSet
执行以下操作:
- 在应用程序中本地缓存数据,以便您可以操作它。如果您只需要读取查询结果,
DataReader
是更好的选择。 - 在应用程序层之间或从 XML Web 服务传输数据。
- 动态与数据交互,例如绑定到 Windows 窗体控件或组合和关联来自多个源的数据。
- 在不需要与数据源建立开放连接的情况下对数据执行大量处理,这样可以释放连接供其他客户端使用。
如果您不需要 DataSet
提供的功能,则可以通过使用 DataReader
以向前、只读方式返回数据来提高应用程序的性能。尽管 DataAdapter
使用 DataReader
来填充 DataSet
的内容,但通过使用 DataReader
,您可以提高性能,因为您可以节省 DataSet
所消耗的内存,并避免创建和填充 DataSet
内容所需的处理。
让我们写一些代码!
每个数据访问场景都将针对一个仅包含两个表的 SQL Server 数据库进行测试
用户
command
-
连接模式(DataReader)
我们这里需要一个有效、打开的连接对象来访问数据存储。DbConnection
类是一个abstract
类,提供程序从中继承以创建特定于提供程序的类。打开和关闭连接
以下代码示例演示了如何首先创建连接,然后使用有效的连接字符串分配连接字符串,您可以打开连接并执行命令。完成连接对象的工作后,必须关闭连接以释放资源。
var connection = new SqlConnection(); connection.ConnectionString = @"Data Source=.;Initial Catalog=codeproject; Integrated Security=SSPI"; connection.Open(); //Process Data here connection.Close();
向数据库发送命令
为了在数据库中处理数据(显示、创建、删除、更新),我们必须使用
SqlCommand
类。例如,假设我们想显示所有命令。SqlCommand myCommand = connection.CreateCommand(); myCommand.CommandText = "select * from command";
从数据库读取数据
在连接模式场景中最重要的类是
SqlDataReader
,它是一个游标,可以逐行读取数据并将其显示给用户,这是连接模式和断开模式之间的唯一区别。SqlDataReader myReader =myCommand.ExecuteReader(); while (myReader.Read ()) //Displaying command names in a ListBox control { CommandListBox.Items.Add(myReader["Name"]); }
所有示例代码
String myConnectionString=@"Data Source=.;Initial Catalog=codeproject;Integrated Security=SSPI"; SqlConnection myConnection=new SqlConnection (myConnectionString); CommandListBox.Items.Clear(); myConnection.Open(); SqlCommand myCommand = myConnection.CreateCommand(); myCommand.CommandText = "select * from Command"; SqlDataReader myReader =myCommand.ExecuteReader(); while (myReader.Read ()) { CommandListBox.Items.Add(myReader["Name"]); } myConnection.Close();
让我们让代码更清晰
在之前的代码中,我们注意到存在许多问题
- SQL 查询和 C# 代码存在于同一个文件中。
- 内存管理不足。
- 缺少异常处理。
String myConnectionString=@"Data Source=.;Initial Catalog=project;Integrated Security=SSPI"; using (SqlConnection myConnection = new SqlConnection(myConnectionString)) { try { myConnection.Open(); SqlCommand myCommand = myConnection.CreateCommand(); myCommand.CommandType = CommandType.StoredProcedure; myCommand.CommandText = "GetListCommands"; while (myReader.Read ()) { CommandListBox.Items.Add(myReader["Name"]); } myConnection.Close(); } catch (Exception) { //Add logging here.... } }
正如您在这里所见,有许多方法可以解决这些问题,例如,我们可以使用
- 存储过程(分离 C# 和 SQL 代码)
Using
块(内存管理)try catch
....(异常处理)
当谈到 C# 代码级别时,连接模式和断开模式之间的唯一区别在于我们想要显示数据时(SqlDataReader
vs SqlDataAdapter
)。在断开模式下,我们将使用 SqlDataAdapter
类,并且还将添加另一个名为 Dataset
的新类,它只不过是一个内存中的数据库。
SqlDataAdapter myAdapter = new SqlDataAdapter(myCommand);
DataSet myDataSet = new DataSet();
myAdapter.Fill(myDataSet);
所有示例代码
String myConnectionString=@"Data Source=.;Initial Catalog=project;Integrated Security=SSPI";
using (SqlConnection myConnection = new SqlConnection(myConnectionString))
{
try
{
myConnection.Open();
SqlCommand myCommand = myConnection.CreateCommand();
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.CommandText = "GetListCommands";
SqlDataAdapter myAdapter = new SqlDataAdapter(myCommand);
DataSet myDataset = new DataSet();
myAdapter.Fill(myDataset);
commandDataGrid.DataSource=myDataset.Tables[0];
myConnection.Close();
}
catch (Exception)
{
//Add logging here....
}
}
ADO.NET 是一个强大的框架,它使开发人员能够使用相同的编程模型访问不同的数据库,但在编写面向对象的应用程序时,您希望考虑问题域并编写面向领域对象和代码。编写数据访问代码和创建可以与数据库通信的数据访问对象感觉像是干扰;它们代表了您应用程序中的噪声。但是,您需要某种方法来将域对象持久化到数据库,这通常意味着创建一个表示关系型数据库的数据模型。Entity Framework 可以提供这个。
在下一节中,我们将看到如何使用 Entity Framework 访问 SQL Server 数据库。
II. ADO.NET
Entity Framework (EF) 是一个开源] 对象关系映射 (ORM) 框架,适用于 ADO.NET,是 .NET Framework 的一部分。您可以从 http://entityframework.codeplex.com/ 下载源代码。
下图说明了用于访问数据的 Entity Framework 体系结构
对象服务是一个组件,它允许开发人员使用实体类型的实例的 CLR 对象来查询数据库(insert
、select
、update
、remove
)。对象服务支持 Linq(语言集成查询)。
此外,ADO.NET(本文第一段)始终用于通过 ADO.NET 数据提供程序查询数据库,该提供程序从 Entity Client Data provider 接收查询,并将一组对象返回给调用者。
Entity Framework 支持两种场景
- 数据库优先 (Database First)
- Code First
Code First 模型 vs. Database First 模型
什么是 Code First 模型?这是指在创建数据库之前创建概念模型。使用 Code First 模型,您可以从概念模型生成数据库,但首先必须手动创建概念模型。Database First 模型允许您从数据库架构生成概念模型,但首先必须手动创建数据库架构。
您应该使用哪种模型?如果数据库或概念模型已存在,您肯定会使用相应的模型。如果什么都不存在,只需采取阻力最小的路径,并从您最熟悉的末端开始工作。就这么简单。
在下一节中,我们将使用 Database First 方法。
步骤
- 打开 Visual Studio(我使用的是 VS 2013)。
- 选择 Visual CSharp 并创建一个 Windows 窗体应用程序。
- Visual Studio 将为您生成一个 Windows 窗体项目。
- 添加一个
DataGrid
和一个按钮。 - 右键单击解决方案资源管理器 => 添加 => 新项 => 数据 => ADO.NET Entity Data Model
- Visual Studio 助手将建议许多选项(Database First、Code First 等),在我们的情况下,我们将选择 Database First。
- 助手将连接到我们的数据库并提取数据(表、存储过程等)。
单击确定,助手将为我们生成访问数据库所需的所有实体。
现在我们有了访问数据库所需的一切,让我们编写一些 C# 代码来显示数据库中 Command
表的数据。
codeprojectEntities db = new codeprojectEntities();
var commands = from cmd in db.Command
select new
{
Name = cmd.Name
};
commandGridView.DataSource = commands.ToList();
//Adding new user
codeprojectEntities db=new codeprojectEntities ();
User user =new User();
User.Nom="Bill G";
Db.User.Add(user);
db.SaveChanges();
您现在可以看到,我们可以基于 OOP(面向对象编程)完成所有操作,没有 SQL 代码,一切都基于概念实体,这是 Entity Framework 等 ORM 的主要目标,它创建了一个抽象层,使应用程序独立于数据库。如果我们想使用 Oracle,例如,编程模型永远不会改变,我们只需安装 Entity Framework 的 Oracle 提供程序。
摘要
通过本文,我们已经看到了一些解释 .NET 如何访问数据库的场景,这些场景使用了两种主要的 .NET Core 技术:
- ADO.NET,即 ADO 的托管版本
- 实体框架
对于 EF,它需要一本书来解释这个数据框架的所有优点和功能。我希望在接下来的文章中,我将深入解释 EF 和两种方法(Database First 和 Code First)。
感谢您的阅读,请尝试下载数据库(DB 的备份),如果您愿意,请不要犹豫留下您的问题、评论和感谢。