首页>教程>ASP.NET教程>Web Forms+Visual Studio入门>Web Forms+Visual Studio入门四-创建数据访问层

需要支持?

如果通过文档没办法解决您的问题,请提交工单获取我们的支持!

Web Forms+Visual Studio入门四-创建数据访问层

本教程系列将介绍如何使用适用于 Web 的 ASP.NET Web Forms 4.5 ASP.NET 2013 Microsoft Visual Studio Express生成应用程序。 本教程Visual Studio 2013随附一个包含 C#源代码的子项目。

本教程介绍如何使用 ASP.NET Web Forms 和 实体框架 Code First 从数据库创建、访问和实体框架 Code First。 本教程基于上一教程”创建Project”,是 Wingtip Toy Store 教程系列的一部分。 完成本教程后,将生成一组数据访问类,这些类在项目的 Models 文件夹中。

学习内容:

  • 如何创建数据模型。
  • 如何初始化和设定数据库种子。
  • 如何更新和配置应用程序以支持数据库。

这些是本教程中引入的功能:

  • 实体框架 Code First
  • LocalDB
  • 数据注释

创建数据模型

实体框架 是 ORM 框架 (对象) 映射。 它使你能够将关系数据作为对象处理,从而消除通常需要编写大部分数据访问代码。 使用 实体框架,可以使用 LINQ发出查询,然后将数据作为强类型对象进行检索和操作。 LINQ 提供用于查询和更新数据的模式。 使用实体框架可以专注于创建应用程序的其余部分,而不是专注于数据访问基础。 本教程系列稍后将介绍如何使用数据填充导航和产品查询。

实体框架支持名为 Code First 的开发范例。 Code First使用 类定义数据模型。 类属于构造,使用类,可以通过组合其他类型的变量、方法和事件创建自己的自定义类型。 可以将类映射到现有数据库,或使用它们生成数据库。 在本教程中,你将通过编写数据模型类来创建数据模型。 然后,你将允许实体框架这些新类创建数据库。

首先创建实体类,这些实体类定义应用程序Web Forms模型。 然后,你将创建一个上下文类,用于管理实体类并提供对数据库的数据访问。 还将创建一个初始值设置项类,该类用于填充数据库。

实体框架和引用

默认情况下,实体框架模板创建新的 ASP.NET Web 应用程序 时,Web Forms 包括。 实体框架包安装、卸载和更新NuGet包。

此NuGet 包包括项目中 的以下运行时程序集:

  • EntityFramework.dll – 应用程序使用的所有公共运行时实体框架
  • EntityFramework.SqlServer.dll – Microsoft SQL Server 的 实体框架 提供程序

实体类

为定义数据的架构而创建的类称为实体类。 如果对数据库设计还很新,可认为实体类是数据库的表定义。 类中的每个属性都指定数据库表中的列。 这些类在面向对象的代码和数据库的关系表结构之间提供轻量的对象关系接口。

在本教程中,首先添加表示产品和类别的架构的简单实体类。 products 类将包含每个产品的定义。 产品类的每个成员的名称将为 ProductID ProductName Description ImagePath UnitPrice CategoryID 、、、 和 Category 。 类别类将包含产品可以属于的每个类别的定义,例如 Car、Plane 或 Plane。 类别类的每个成员的名称将为 CategoryID CategoryName Description 、、 和 Products 。 每个产品将属于其中一个类别。 这些实体类将添加到项目的现有 Models 文件夹中。

  1. 在 解决方案资源管理器 中,右键单击”模型” 文件夹,然后选择”添加新 – > 项”。创建数据访问层 - 新建项菜单随即出现“添加新项”对话框。
  2. 在 左侧”已安装”窗格中的”Visual C#” 下,选择”代码 “。创建数据访问层 - 新建项菜单
  3. 从 中间 窗格中选择”类”,并命名此新类 Product.cs
  4. 单击“添加”。
    新的类文件将显示在编辑器中。
  5. 将默认代码替换为以下代码:C#代码
using System.ComponentModel.DataAnnotations;

namespace WingtipToys.Models
{
    public class Product
    {
        [ScaffoldColumn(false)]
        public int ProductID { get; set; }

        [Required, StringLength(100), Display(Name = "Name")]
        public string ProductName { get; set; }

        [Required, StringLength(10000), Display(Name = "Product Description"), DataType(DataType.MultilineText)]
        public string Description { get; set; }

        public string ImagePath { get; set; }

        [Display(Name = "Price")]
        public double? UnitPrice { get; set; }

        public int? CategoryID { get; set; }

        public virtual Category Category { get; set; }
    }
}

6.通过重复步骤 1 到步骤 4 创建另一个类,但是,将新类 命名 Category.cs, 将默认代码替换为以下代码:C#代码

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace WingtipToys.Models
{
    public class Category
    {
        [ScaffoldColumn(false)]
        public int CategoryID { get; set; }

        [Required, StringLength(100), Display(Name = "Name")]
        public string CategoryName { get; set; }

        [Display(Name = "Product Description")]
        public string Description { get; set; }

        public virtual ICollection<Product> Products { get; set; }
    }
}

如前所述, 类表示应用程序旨在销售 (的产品类型,如汽车、飞行、火箭 Category ” ” 等 ” ” ” “) , Product 类表示数据库中 (玩具) 的单个产品。 对象的每个实例将对应于关系数据库表中的行,并且 Product 类的每个属性都将映射到关系 Product 数据库表中的列。 在本教程的稍后部分,你将查看数据库中包含的产品数据。

数据注释

你可能已注意到,类的某些成员具有指定有关成员的详细信息的属性,例如 [ScaffoldColumn(false)] 。 这些是 数据注释。 数据注释属性可以描述如何验证该成员用户输入、指定其格式以及指定创建数据库时如何建模。

Context 类

若要开始使用类进行数据访问,必须定义上下文类。 如前所述,上下文类管理实体类 (如 类和类) 并提供 Product Category 对数据库的数据访问。

此过程将新的 C# 上下文类添加到 Models 文件夹。

  1. 右键单击 “Models” 文件夹,然后选择”添加新 – > 项”。
    随即出现“添加新项”对话框。
  2. 从 中间窗格中 选择”类”,将其命名 “ProductContext.cs”, 然后单击”添加 “。
  3. 将 类中包含的默认代码替换为以下代码:C#代码
using System.Data.Entity;
namespace WingtipToys.Models
{
    public class ProductContext : DbContext
    {
        public ProductContext() : base("WingtipToys")
        {
        }
        public DbSet<Category> Categories { get; set; }
        public DbSet<Product> Products { get; set; }
    }
}

此代码添加 命名空间,以便可以访问 实体框架 的所有核心功能,其中包括通过使用强类型对象查询、插入、更新和删除数据 System.Data.Entity 的功能。

类表示实体框架数据库上下文,用于处理提取、存储和更新 ProductContext Product 数据库中的类实例。 类 ProductContext 派生自 实体框架 提供的 DbContext 基实体框架。

Initializer 类

首次使用上下文时,需要运行一些自定义逻辑来初始化数据库。 这样,就可以将种子数据添加到数据库,以便你可以立即显示产品和类别。

此过程会将新的 C# 初始值设置项类添加到 Models 文件夹。

  1. 在 Models Class 文件夹中创建 另一 个 ,将其命名为 ProductDatabaseInitializer.cs
  2. 将 类中包含的默认代码替换为以下代码:C#代码
using System.Collections.Generic;
using System.Data.Entity;

namespace WingtipToys.Models
{
  public class ProductDatabaseInitializer : DropCreateDatabaseIfModelChanges<ProductContext>
  {
    protected override void Seed(ProductContext context)
    {
      GetCategories().ForEach(c => context.Categories.Add(c));
      GetProducts().ForEach(p => context.Products.Add(p));
    }

    private static List<Category> GetCategories()
    {
      var categories = new List<Category> {
                new Category
                {
                    CategoryID = 1,
                    CategoryName = "Cars"
                },
                new Category
                {
                    CategoryID = 2,
                    CategoryName = "Planes"
                },
                new Category
                {
                    CategoryID = 3,
                    CategoryName = "Trucks"
                },
                new Category
                {
                    CategoryID = 4,
                    CategoryName = "Boats"
                },
                new Category
                {
                    CategoryID = 5,
                    CategoryName = "Rockets"
                },
            };

      return categories;
    }

    private static List<Product> GetProducts()
    {
      var products = new List<Product> {
                new Product
                {
                    ProductID = 1,
                    ProductName = "Convertible Car",
                    Description = "This convertible car is fast! The engine is powered by a neutrino based battery (not included)." + 
                                  "Power it up and let it go!", 
                    ImagePath="carconvert.png",
                    UnitPrice = 22.50,
                    CategoryID = 1
               },
                new Product 
                {
                    ProductID = 2,
                    ProductName = "Old-time Car",
                    Description = "There's nothing old about this toy car, except it's looks. Compatible with other old toy cars.",
                    ImagePath="carearly.png",
                    UnitPrice = 15.95,
                     CategoryID = 1
               },
                new Product
                {
                    ProductID = 3,
                    ProductName = "Fast Car",
                    Description = "Yes this car is fast, but it also floats in water.",
                    ImagePath="carfast.png",
                    UnitPrice = 32.99,
                    CategoryID = 1
                },
                new Product
                {
                    ProductID = 4,
                    ProductName = "Super Fast Car",
                    Description = "Use this super fast car to entertain guests. Lights and doors work!",
                    ImagePath="carfaster.png",
                    UnitPrice = 8.95,
                    CategoryID = 1
                },
                new Product
                {
                    ProductID = 5,
                    ProductName = "Old Style Racer",
                    Description = "This old style racer can fly (with user assistance). Gravity controls flight duration." + 
                                  "No batteries required.",
                    ImagePath="carracer.png",
                    UnitPrice = 34.95,
                    CategoryID = 1
                },
                new Product
                {
                    ProductID = 6,
                    ProductName = "Ace Plane",
                    Description = "Authentic airplane toy. Features realistic color and details.",
                    ImagePath="planeace.png",
                    UnitPrice = 95.00,
                    CategoryID = 2
                },
                new Product
                {
                    ProductID = 7,
                    ProductName = "Glider",
                    Description = "This fun glider is made from real balsa wood. Some assembly required.",
                    ImagePath="planeglider.png",
                    UnitPrice = 4.95,
                    CategoryID = 2
                },
                new Product
                {
                    ProductID = 8,
                    ProductName = "Paper Plane",
                    Description = "This paper plane is like no other paper plane. Some folding required.",
                    ImagePath="planepaper.png",
                    UnitPrice = 2.95,
                    CategoryID = 2
                },
                new Product
                {
                    ProductID = 9,
                    ProductName = "Propeller Plane",
                    Description = "Rubber band powered plane features two wheels.",
                    ImagePath="planeprop.png",
                    UnitPrice = 32.95,
                    CategoryID = 2
                },
                new Product
                {
                    ProductID = 10,
                    ProductName = "Early Truck",
                    Description = "This toy truck has a real gas powered engine. Requires regular tune ups.",
                    ImagePath="truckearly.png",
                    UnitPrice = 15.00,
                    CategoryID = 3
                },
                new Product
                {
                    ProductID = 11,
                    ProductName = "Fire Truck",
                    Description = "You will have endless fun with this one quarter sized fire truck.",
                    ImagePath="truckfire.png",
                    UnitPrice = 26.00,
                    CategoryID = 3
                },
                new Product
                {
                    ProductID = 12,
                    ProductName = "Big Truck",
                    Description = "This fun toy truck can be used to tow other trucks that are not as big.",
                    ImagePath="truckbig.png",
                    UnitPrice = 29.00,
                    CategoryID = 3
                },
                new Product
                {
                    ProductID = 13,
                    ProductName = "Big Ship",
                    Description = "Is it a boat or a ship. Let this floating vehicle decide by using its " + 
                                  "artifically intelligent computer brain!",
                    ImagePath="boatbig.png",
                    UnitPrice = 95.00,
                    CategoryID = 4
                },
                new Product
                {
                    ProductID = 14,
                    ProductName = "Paper Boat",
                    Description = "Floating fun for all! This toy boat can be assembled in seconds. Floats for minutes!" + 
                                  "Some folding required.",
                    ImagePath="boatpaper.png",
                    UnitPrice = 4.95,
                    CategoryID = 4
                },
                new Product
                {
                    ProductID = 15,
                    ProductName = "Sail Boat",
                    Description = "Put this fun toy sail boat in the water and let it go!",
                    ImagePath="boatsail.png",
                    UnitPrice = 42.95,
                    CategoryID = 4
                },
                new Product
                {
                    ProductID = 16,
                    ProductName = "Rocket",
                    Description = "This fun rocket will travel up to a height of 200 feet.",
                    ImagePath="rocket.png",
                    UnitPrice = 122.95,
                    CategoryID = 5
                }
            };

      return products;
    }
  }
}

如上面的代码所示,创建和初始化数据库时,将 Seed 重写和设置 属性。 设置 Seed 属性后,类别和产品中的值将用于填充数据库。 如果在创建数据库后尝试通过修改上述代码来更新种子数据,则运行 Web 应用程序时将看不到任何更新。 原因是上述代码使用 类的实现来识别在重置种子数据 (架构) 是否 DropCreateDatabaseIfModelChanges 已更改。 如果未对 和 实体类进行更改,将不会使用种子数据重新初始化 Category Product 数据库。

备注

如果希望每次运行应用程序时都重新创建数据库,可以使用 类 DropCreateDatabaseAlways 而不是 DropCreateDatabaseIfModelChanges 类。 但是,对于本教程系列,请使用 DropCreateDatabaseIfModelChanges 类。

在本教程的此时,你将有一个 Models 文件夹,该文件夹包含四个新类和一个默认类:

创建数据访问层 - Models 文件夹

将应用程序配置为使用数据模型

创建表示数据的类后,必须将应用程序配置为使用类。 在 Global.asax 文件中,添加用于初始化模型的代码。 在 Web.config 文件中添加信息,告知应用程序你将使用什么数据库来存储由新数据类表示的数据。 Global.asax 文件可用于处理应用程序事件或方法。 使用 Web.config 文件可以控制 web 应用程序的 ASP.NET 配置。

更新 Global.asax 文件

若要在应用程序启动时初始化数据模型,请更新 Application_Start Global.asax.cs 文件的 处理程序。

备注

在解决方案资源管理器中,可以选择 Global.asax 文件或 Global.asax.cs 文件来编辑 Global.asax.cs 文件。

  1. 将以加粗显示的以下代码添加到 Application_Start Global.asax.cs 文件的 方法。C#代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Optimization;
using System.Web.Routing;
using System.Web.Security;
using System.Web.SessionState;
using System.Data.Entity;
using WingtipToys.Models;

namespace WingtipToys
{
    public class Global : HttpApplication
    {
        void Application_Start(object sender, EventArgs e)
        {
            // Code that runs on application startup
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            // Initialize the product database.
            Database.SetInitializer(new ProductDatabaseInitializer());
        }
    }
}

如上面的代码所示,应用程序启动时,应用程序指定将在首次访问数据期间运行的初始值设置程序。 需要另外两个命名空间才能访问 Database 对象和 ProductDatabaseInitializer 对象。

修改Web.Config文件

尽管实体框架 Code First填充种子数据时,用户将在默认位置生成数据库,但向应用程序添加自己的连接信息可让你控制数据库位置。 在应用程序的根目录文件中,使用 Web.config字符串指定 此数据库连接。 通过添加新的连接字符串,可以将数据库 (wingtiptoys.mdf) 的位置引导到应用程序的数据目录 (应用数据) 中,而不是其默认位置。 _ 进行此更改将允许你在本教程的稍后部分查找和检查数据库文件。

  1. 在 解决方案资源管理器 中,找到并打开 Web.config文件 。
  2. 将以加粗显示的连接字符串添加到Web.config<connectionStrings> 文件的部分,如下所示:XML代码
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\aspnet-WingtipToys-20131119102907.mdf;Initial Catalog=aspnet-WingtipToys-20131119102907;Integrated Security=True"
providerName="System.Data.SqlClient" />
<add name="WingtipToys"
connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\wingtiptoys.mdf;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>

首次运行应用程序时,它将在连接字符串指定的位置生成数据库。 但在运行应用程序之前,让我们先生成它。

生成应用程序

若要确保 Web 应用程序的所有类和更改都正常工作,应生成应用程序。

  1. 在”调试” 菜单中,选择”生成 WingtipToys”。
    将显示  输出”窗口,如果一切顺利,则会看到 成功 消息。创建数据访问层 - 输出Windows

如果遇到错误,请重新检查上述步骤。 “输出 “窗口中 的信息将指示哪个文件有问题,以及文件中需要更改的位置。 此信息将让你确定需要检查和修复项目中上述步骤的哪一部分。

总结

在本系列教程中,你已创建数据模型,并添加了用于初始化和设定数据库种子的代码。 你还将应用程序配置为在应用程序运行时使用数据模型。

下一教程将更新 UI、添加导航以及从数据库中检索数据。 这将基于在本教程中创建的实体类自动创建数据库。

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
今日签到
有新私信 私信列表
搜索