在.NET开发中使用Entity Framework 4.3






4.80/5 (11投票s)
本文介绍了如何在Windows桌面或Web应用程序中使用Entity Framework版本4.3进行数据库访问。
引言
本文通过一个教程介绍了如何使用Entity Framework构建应用程序。Entity Framework使开发人员能够通过针对概念应用程序模型进行编程来创建数据访问应用程序,而不是直接针对关系存储架构进行编程。目标是减少数据导向应用程序所需的代码量和维护工作。
最终产品将是一组使用Entity Framework查询和更新数据库的单元测试。此代码可用于您的数据导向应用程序以进行数据访问和更新。没有使用ADO.NET代码与数据库进行通信。返回的对象是可枚举类型,可以使用LINQ进行遍历。
开发环境
本教程需要以下应用程序。假设您对Visual Studio 2010或2012版本有一定经验,并且已将其安装在您的计算机上。
NuGet包管理器不是必需的,但强烈建议用于安装Entity Framework等外部组件。它不仅会将库复制到您的VS解决方案,还会自动在您的项目中创建对这些库的引用。
NuGet包管理器可以从以下链接下载,它是本教程的一部分:http://visualstudiogallery.msdn.microsoft.com/27077b70-9dad-4c64-adcf-c7cf6bc9970c/。
- .NET Framework 4.5
- Visual Studio 2012
- Visual Studio 2012的NuGet包管理器扩展
- SQL Server 2005或更高版本
设置数据库
需要执行的第一步是安装AdventureWorks SQL 2008 R2 OLTP数据库。访问Microsoft CodePlex上AdventureWorks的页面http://msftdbprodsamples.codeplex.com/releases/view/59211,下载MDF文件。将MDF文件复制到您的SQL Server帐户具有适当读取权限的文件夹中。根据您的SQL Server版本,您的超级用户帐户可能没有权限读取下载文件夹中的文件。您还可以调整下载文件夹中SQL Server超级用户帐户的ACL。
然后打开SQL Server Management Studio并输入以下命令
CREATE DATABASE AdventureWorks ON (
FILENAME = 'C:\Users\Public\AdventureWorks2008R2_Data.mdf') FOR ATTACH_REBUILD_LOG;
此命令将把MDF文件附加到您的SQL Server实例,并为数据库创建日志(LDF)文件。刷新您的数据库以查看新的AdventureWorks数据库。
在本教程中,我们将创建一些视图和一个存储过程。我希望我的数据访问代码与数据库架构的更改无关,所以我更喜欢将Entity Framework模型(我将在稍后创建)链接到视图而不是表。但是,您可以将实体直接链接到表。Product实体的更新方法将通过存储过程dbo.updateProduct完成,所以我也包含了它。
CREATE VIEW [dbo].[Products]
AS
SELECT ProductID, Name, ProductNumber, ListPrice, StandardCost, ProductSubcategoryID, ProductModelID
FROM Production.Product
GO
CREATE VIEW [dbo].[ProductSubcategories]
AS
SELECT ProductSubcategoryID, Name
FROM Production.ProductSubcategory
GO
CREATE VIEW [dbo].[ProductModels]
AS
SELECT Name, ProductModelID
FROM Production.ProductModel
GO
CREATE VIEW [dbo].[ProductSearchItems]
AS
SELECT
Production.Product.ProductID AS ProductId
,Production.Product.Name AS ProductName
,Production.Product.ProductNumber AS ProductNumber
,Production.ProductCategory.Name AS ProductCategory
,Production.ProductModel.Name AS ProductModel
,Production.ProductSubcategory.Name AS ProductSubcategory
FROM Production.Product INNER JOIN
Production.ProductModel ON Production.Product.ProductModelID =
Production.ProductModel.ProductModelID INNER JOIN
Production.ProductSubcategory ON Production.Product.ProductSubcategoryID =
Production.ProductSubcategory.ProductSubcategoryID INNER JOIN
Production.ProductCategory ON Production.ProductSubcategory.ProductCategoryID =
Production.ProductCategory.ProductCategoryID
GO
CREATE VIEW [dbo].[TransactionHistory]
AS
SELECT TransactionID, ProductID, TransactionDate, TransactionType, Quantity, ActualCost, ModifiedDate
FROM Production.TransactionHistory
GO
CREATE PROCEDURE dbo.updateProduct
@productId int,
@productName nvarchar(50),
@productNumber nvarchar(25),
@listPrice money,
@standardCost money,
@productSubcategoryId int,
@productModelId int
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
UPDATE Production.Product
SET Name = @productName,
ProductNumber = @productNumber,
ListPrice = @listPrice,
StandardCost = @standardCost,
ProductSubcategoryID = @productSubcategoryId,
ProductModelID = @productModelId
WHERE ProductID = @productId
END
GO
创建解决方案
下一步是创建Visual Studio解决方案。对于本教程,请使用.NET Framework 4.5创建一个包含单个类库项目的解决方案。
在本练习中,我将解决方案命名为“AdventureWorks”,项目命名为“AdventureWorksService”(因为我将来会有一个AdventureWorksWeb项目将使用此库)。
设置Entity Framework
下一步是安装Entity Framework。安装Visual Studio的NuGet包管理器扩展后,转到工具 -> 库包管理器 -> 包管理器控制台。NuGet控制台将出现。在控制台中键入“Install-Package EntityFramework -Version 4.3.1”并按ENTER。这将把Entity Framework 4.3.1版本的库复制到您的解决方案中的“packages”文件夹,并自动将这些库的引用添加到您的项目中,以便您可以立即使用它们。
生成实体数据模型
在解决方案资源管理器中,右键单击您创建的类库项目,然后选择添加 -> 新建项。在“添加新项”框中,选择Visual C# 项 -> 数据,然后选择ADO.NET实体数据模型。为EMDX文件命名。在我的示例中,我将其命名为“AdventureWorksEntities.emdx”。
实体数据模型向导为您提供了创建空白实体模型或从数据库生成实体模型的选项。在本教程中,我们将从AdventureWorks数据库生成一个。选择“从数据库生成”选项,然后单击“下一步”。向导中的后续步骤将帮助您在app.config文件中创建Entity Framework连接字符串。如果这是您第一次使用此向导,您将没有保存的连接字符串,您需要单击“新建连接”来创建新的连接字符串。选择您要使用的SQL Server实例,然后选择AdventureWorks数据库。当您完成向导时,它将确认您的SQL Server实例和Adventureworks数据库的连接信息。我的SQL连接字符串的图片如下所示,但根据您的SQL Server安装情况,它将有所不同。
点击“下一步”按钮,选择您在前面步骤中为实体模型创建的数据库对象。打开“视图”并选择ProductModels、Products、ProductSearchItems、ProductSubcategories和TransactionHistory视图。在“存储过程”中,选择dbo.updateProduct。
所有选项都应已勾选。
单击“完成”按钮,让Entity Framework为您生成实体。完成后,您将有五个实体类型,每个类型对应一个视图。现在我们将存储过程链接到实体模型。右键单击“Products”实体,然后选择“存储过程映射”。单击“选择更新函数”,然后在下拉列表中选择“updateProduct”。Entity Framework将分析updateProduct存储过程,并提示您将Product实体中的字段映射到存储过程的输入参数。如下图所示输入字段。这将指示Entity Framework在调用Save方法时使用Product实体的相应字段。
默认情况下,Entity Framework会将所有非外键字段作为实体键,因此我们需要在Product实体中关闭此功能,以便Save函数正常工作。再次选择Product实体,然后选择Name字段。在“属性”部分中,将“实体键”值更改为False。对ProductNumber、ListPrice和StandardCost执行相同的操作。这将允许我们在Save函数中更新这些字段。
本练习的最后一步是创建模拟网站功能的测试。这些测试将执行以下功能:
- 按名称或编号搜索产品。
- 返回所有可用的产品模型。
- 返回所有可用的产品子类别。
- 按产品ID返回产品详细信息。
- 按产品ID返回产品的全部交易历史。
- 更新产品。
我创建了一个单独的单元测试项目并引用了AdventureWorksService项目。我还需要引用System.Data和System.Data.Entity DLLs来实现Entity Framework功能。下面的单元测试将使用您在前面步骤中创建的实体来测试以上所有六个场景。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using AdventureWorksService.Entities;
namespace UnitTests
{
[TestClass]
public class EntityTests
{
[TestMethod]
public void SearchProducts()
{
string searchCriteria = "bike";
using (AdventureWorksEntities _db = new AdventureWorksEntities())
{
List<ProductSearchItem> products = (from s in _db.ProductSearchItems
where s.ProductName.Contains(searchCriteria) ||
s.ProductNumber.Contains(searchCriteria) select s).ToList();
}
}
[TestMethod]
public void GetProductModes()
{
using (AdventureWorksEntities _db = new AdventureWorksEntities())
{
List<ProductModel> productModels = (from m in _db.ProductModels select m).ToList();
}
}
[TestMethod]
public void GetProductSubcategories()
{
using (AdventureWorksEntities _db = new AdventureWorksEntities())
{
List<ProductSubcategory> productSubcategories =
(from s in _db.ProductSubcategories select s).ToList();
}
}
[TestMethod]
public void GetProductDetails()
{
int productId = 879;
using (AdventureWorksEntities _db = new AdventureWorksEntities())
{
Product product = _db.Products.First(p => p.ProductID == productId);
}
}
[TestMethod]
public void GetTransactionHistory()
{
using (AdventureWorksEntities _db = new AdventureWorksEntities())
{
int productId = 879;
List<TransactionHistory> transactionHistoryCollection = (from t in _db.TransactionHistories
where t.ProductID == productId
select t).ToList();
}
}
[TestMethod]
public void UpdateProduct()
{
int productId = 879;
using (AdventureWorksEntities _db = new AdventureWorksEntities())
{
Product product = _db.Products.First(p => p.ProductID == productId);
product.Name = "All-Purpose Bike Stand";
product.ProductNumber = "ST-1401";
product.StandardCost = 59.46m;
product.ListPrice = 159.00m;
product.ProductModelID = 122;
product.ProductSubcategoryID = 27;
_db.SaveChanges();
}
}
}
}
AdventureWorkEntities
是创建实体数据模型时生成的Entity Framework数据库上下文类的名称。将此类的实例化包装在using语句中,以确保对象得到正确释放。上下文类允许您使用LINQ语法查询数据库。连接数据库、打开SQL命令和加载SQLReader的ADO.NET样板代码由Entity Framework内部处理。
因为我为实体单元测试创建了一个单独的项目,所以我必须将Entity Framework配置从我的服务项目复制到我的单元测试项目的app.config中。这对于Entity Framework从单元测试内部连接到数据库是必要的。当然,如果您的单元测试与您的实体在同一个项目中,则不需要这样做。如果您在Web项目中使用此代码,则需要将配置复制到您的web.config中。
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration,
visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework"
type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework,
Version=4.3.1.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</configSections>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework">
<parameters>
<parameter value="Data Source=.\SQLEXPRESS; Integrated Security=True; MultipleActiveResultSets=True" />
</parameters>
</defaultConnectionFactory>
</entityFramework>
<connectionStrings>
<add name="AdventureWorksEntities"
connectionString="metadata=res://*/Entities.AdventureWorksEnities.csdl|res://*/
Entities.AdventureWorksEnities.ssdl|res://*/Entities.AdventureWorksEnities.msl;
provider=System.Data.SqlClient;provider connection string="
data source=OWNER-PC\SQLEXPRESS;initial catalog=AdventureWorks;
integrated security=True;multipleactiveresultsets=True;App=EntityFramework""
providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>
我希望您喜欢本教程,如果您正在学习使用Entity Framework,我希望它对您有所帮助。您可以在CodePlex上的以下位置下载完整的源代码:http://adventureworksportal.codeplex.com。
它包含带有Entity Framework的服务项目和使用的Web项目的源代码(我将在我的下一个教程中讨论)。
请随时回复评论和问题。