介绍
本文的目的是解释微软的实体框架提供的三种数据访问方法。网上有好几篇关于这个话题的好文章,但是我想以一个教程的形式更详细地介绍这个话题,这个教程对于开始学习实体框架及其方法的人来说是个入门。我们将逐步探索每个方法,通过这些方法,我们可以在应用程序中使用实体框架访问数据库和数据。我将使用实体框架版本6.2和.NETFramework 4.6。和Visual Studio 2017的教程。对于数据库,我们将使用SQLServer。如果没有安装SQLServer,则可以使用本地数据库。我将在本文中首先解释数据库和模型优先方法,并在下一篇文章中解释代码优先方法和代码优先迁移。
实体框架
微软实体框架是ORM(对象-关系映射)。*的定义对于ORM和PITY非常简单。
计算机科学中的对象关系映射(ORM、O/RM和O/R映射工具)是一种使用面向对象的编程语言在不兼容类型系统之间转换数据的编程技术。实际上,这将创建一个可以从编程语言中使用的“虚拟对象数据库”。
作为一个ORM,实体框架是由Microsoft提供的数据访问框架,它有助于在应用程序中建立对象和数据结构之间的关系。它是通过传统的ADO.NET构建的,并作为ADO.NET上的包装器。它是对ADO.NET的一种增强,它以更加自动化的方式提供数据访问,从而减少了开发人员与连接、数据读取器或数据集的斗争。它是对所有这些的抽象,对它所做的贡献更为强大。开发人员可以对他所需要的数据、形式和数量有更多的控制权。没有数据库开发背景的开发人员可以利用实体框架和LINQ能力编写优化查询来执行DB操作。SQL或DB查询执行将由后台实体框架处理,它将处理可能发生的所有事务和并发问题。EntityFrameworkTutorial是一个网站,您可以通过它深入了解这个概念,并理解它的工作模型、体系结构等等。
实体框架方法
了解微软实体框架提供的三种方法是非常常见的。三种方法如下:
- 模型优先
- 数据库优先
- 代码优先
从数据模型类生成数据库。
从现有数据库生成数据模型类。
模型第一种方法说,我们有一个模型,该模型具有各种实体和关系/关联,使用该模型,我们可以生成一个数据库,最终将实体和属性转换为数据库表,列和关系将转换为外部分别是密钥。
数据库第一方法表示,我们已经有一个现有的数据库,我们需要在我们的应用程序中访问该数据库。我们可以直接从数据库创建实体数据模型及其关系,只需要几次单击即可开始从我们的代码访问数据库。所有实体,例如,类将由实体框架生成,实体框架可用于应用程序数据访问层以参与DB操作查询。
代码优先方法是EF的推荐方法,尤其是在从头开始开发应用程序时。您可以预先定义POCO类,以及它们的关系,并通过在代码中定义结构来想象数据库结构和数据模型的样子。最后,实体框架将负责为您的POCO类和数据模型生成数据库,并负责事务、历史和迁移。
通过这三种方法,您可以完全控制在任何时间点按需要更新数据库和代码。
模型优先
使用模型第一方法,开发人员可能不需要编写任何代码来生成数据库。实体框架提供了设计器工具,这些工具可以帮助您创建模型,然后从中生成数据库。这些工具更多的是拖放控件,它们只需要输入,比如实体名是什么、应该具有什么属性、与其他实体如何相关等等。用户界面是非常容易使用和有趣的。模型设计器(如果可以的话)将帮助您生成DDL命令,这些命令可以直接从Visual Studio或在您的数据库服务器上执行,以便从您创建的模型创建数据库。这将创建一个EDMX文件,该文件存储概念模型、存储模型和两者之间的映射信息。要了解概念模型和存储模型,可以参考本文介绍中所提供的链接。我能够看到的唯一缺点是,完全删除数据库并重新创建数据库将是这种方法的挑战。
数据库优先
当我们已经有一个现有的数据库并且需要在我们的应用程序中访问时,我们首先使用数据库的方法。使用实体框架为现有数据库建立数据访问方法将帮助我们在解决方案中生成上下文和类,通过这些上下文和类我们可以访问数据库。这是模型第一种方法的反面。这里,模型是通过数据库创建的,我们可以完全控制在模型中包括哪些表,以及包括哪些存储过程、函数或视图。您的应用程序可能是一个子应用程序,它不需要大型数据库的所有表或对象,因此您可以在这里*地控制应用程序中所需的内容和应用程序中不需要的内容。每当数据库模式改变时,只需单击设计器或实体数据模型即可轻松更新实体数据模型,这将负责映射并在应用程序中创建必要的类。
代码优先
使用代码第一方法,开发人员的重点只在代码上,而不是在数据库或数据模型上。开发人员可以在代码本身中定义类及其映射,由于现在实体框架支持继承,所以更容易定义关系。实体框架负责为您创建或重新创建数据库,不仅如此,在创建数据库时,还可以提供种子数据。例如,当创建数据库时,您希望您的表具有主数据。首先使用代码,您可能没有具有关系和模式的.edmx文件,因为它不依赖于实体框架设计器及其工具,并且由于您是创建类和关系并管理数据库的人,因此将对数据库有更多的控制。出现了代码优先迁移的新概念,这使得代码优先方法更易于使用和遵循,但在本文中,我将不使用迁移,而是使用创建DB上下文和DB集类的旧方法,以便您了解隐藏的内容。代码优先方法还可以用于从现有数据库生成代码,因此它基本上提供了两种可以使用的方法。
行动中的实体框架方法
足够的理论,让我们从执行部分开始,一步一步地一步一步地探索和学习每一种方法。我将使用一个示例项目,并将其用于控制台应用程序,以使用实体框架连接数据库。我会用基本的样本表来解释这个概念。这里的目的是学习概念并实现它,而不是创建一个大的应用程序。When you learn it, you can use the concepts with any large enterprise level application or any big database server which can have thousands of tables. 所以,我们将遵循接吻策略,并在这里保持简单。
模型优先
- Create a simple .NET Framework console application by opening your visual studio and choosing the console application template. We can choose any application type like a web application that could be ASP.NET web forms, MVC or Web API or windows application/WPF application. You can give a name to the project and solution of your choice.
- We’ll have Program.cs, the only class and App.config in our project.
- Right-click the project and click on add a new item, this will open the window to add a new item, just go to Data as shown in below image and choose ADO.NET Entity Data Model as shown in the following image. Give it a name. For example, EFModel and click on Add.
- Once you click add, you’ll be shown to choose Model Contents, and this is the place where you choose what approach you want to use for data access out of the three EF approaches. So, choose Empty EF Designer because we would be using model first approach and create a model from scratch.
- Once you click "Finish", you see the empty designer window that is the .edmx file. The name of the .edmx file in solution is the name that we provided while adding the EF designer model. In the toolbox, you see the tools available that you could use to create entities and associations between them.
- Drag and drop the Entity tool from the toolbox into the designer. It will create an empty entity as shown below with one property named Id, saying it is a primary key. Here you can rename the entity and add more scalar properties.
- Right click on entity created and add a new scalar property as shown in the following image. Rename the name of the entity from Entity1 to Student. You can rename the entity by double-clicking on the entity name and right click and rename the entity.
- Name the scalar property as "Name".
- In an analogous way add a new entity named
Class
and add a new property namedClassName
. We here are trying to create a student and a class relationship where a class can have multiple students. So, we have an option to choose Association from toolbox as shown below and drag the Association tool from Class to Student and it showed 1 to many relationship.
- We are not adding more entities and try to understand the basic functionality with these two entities. Right click on the designer and click on "Generate Database from Model…" option to generate the scripts.
- Once you click on "Generate Database from Model…" option, you’ll be asked to choose data connection as shown in the following window. You can choose a new connection or an existing one. I’ll choose a new connection but before that, I’ll create an empty database on my SQL server so that I do not have to modify my scripts to provide a database name. By default, the generated scrips create tables in the master database if DB name is not specified.
- Open your SQL Server and create a new database and name it as per your choice. I am naming it StudentDB as shown in the following images.
- Coming back to the window where we needed to provide the connection details. Choose your data source and server name as shown in the following image. The server name should be the server where you created the empty database. Now in the selecting database option, expand the dropdown and you should see your database name. Select the database name.
- Once you select the database name, a connection string would be generated as shown below and it will say that the connection string would be saved I the App.Config file with the name
EFModelContainer
.EFModelContainer
is the name of the connection string. Since it is an EF generated connection string, you see it has the information about EF CSDL, MSL and SSDL files as well that would be present in our application. Click Next to proceed.
- Next step is to choose your Entity Framework version. We’ll use 6.x i.e. it will automatically pick the latest stable version with EF6. Click Next.
- As a last step of the wizard, you’ll see the needed SQL scripts created for us. You can choose to rename the scripts but by default, it takes the name as <model name>.edmx.sql. I’ll leave it as it is and click Finish to proceed.
- You’ll see the script located in solution explorer now. Double click to open it and it opens in a window where you have an option to directly execute it.
- Before executing the scripts let’s first install Entity Framework latest stable version from the Nuget package manager. It is very simple to do. Go to Tools in Visual Studio, then choose NuGet Package Manager->Package Manager Console as shown in the following image.
- The NuGet Package Manager console window will be opened at the bottom of Visual Studio by default. Now choose the project for which the Entity Framework package needs to be installed. And in the command that says PM> type Install-Package EntityFramework and press enter. We do not specify the version of entity framework as we want the latest stable package should be downloaded and added to our project as a DLL reference.
- Once done with installing Entity Framework, go back to the script window and on the top left, you see the button to execute the scripts as shown below. Press the button to execute the scripts.
- Once you click on Execute, a new window will show up asking server and database details. Fill in the details specific to your server and database as shown below and click Connect.
- Once done, go to your database server and you’ll see the tables are created for our database StudentDB. The names of the tables are pluralized, and Student table has a foreign key reference to Classes table and the foreign key is automatically created named
Class_Id
referencing Classes table. It is magical, isn’t it?
- In our solution explorer, we see the .edmx file and the context classes created and model classes for Student and Class entities. This is all done in the background by EF designer. So, till now we did not write a single code and got all the code generated by EF.
- Open the EFModel.Context.cs class file and we see the name of the
DbContext
class that got generated isEFModelContainer
. Remember that is the name of our connection string stored in App.Config. The name of the context class has to be the same as connection string name for EF to know the relation. So, you can have multiple DB context classes in the same solution with different names and pointing to different connection strings. You can explore more onDbContext
class and what other ways you can make its relation to the connection string in the config file. One another way is to call its base constructor by passing name of the connection string as a parameter to its parameterized constructor. But for the sake of understanding, we’ll stick to this implementation.
- Now it’s time to test our implementation and check if the entity framework is actually working and helping us in database operations or not. So, in the Program.cs class’s
Main
method we’ll try to write some code that saves a new class for us in the database. Create a new object of EFModelContainer and in the container, we get the entity classes collection coming fromDbContext
. Add a new Class. The class is the name of the entity class generated for us via designer. And name the class as "Nursery". We do not have to specify the id attribute for the class, as EF will automatically handle this and provide an Id to a newly added record. The code to add a new class named "Nursery" is shown in the following image. Thecontainer.SaveChanges
statement is the statement when executed will add a new record in the database for us.
- Just run the application and let the main method code execute. Once done, go to your database and check the Classes table, you’ll see a new record is added in the Classes table with the class name "Nursery" which is what we provided while wanted to add a record. So, it works