65.9K
CodeProject 正在变化。 阅读更多。
Home

Entity Framework Code First 方法,使用数据注解和 Fluent API

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.82/5 (13投票s)

2014年7月4日

CPOL

6分钟阅读

viewsIcon

53236

downloadIcon

3

Entity Framework 的各种方法,以及 Code First 方法的示例

引言

我计划在后续一系列文章中介绍 Entity Framework 的一些重要功能。我希望它能帮助从新手到经验丰富的 .NET 开发人员。

我假设您已经熟悉“Entity Framework”这个术语,并且想了解更多关于它的信息。那么您来对地方了。是的,Entity Framework 是微软的 ORM(对象关系映射器)。我之所以说是微软的产品,是因为有许多其他厂商也有类似的产品。NHibernate 就是其中之一,它提供了类似的功能。让我们来理解“对象关系映射器”这个术语。在这里,对象就是我们的类,而关系则代表存储在数据库中的表。在过去,开发人员会手动编写代码来获取数据,并将数据转换为领域对象,然后跨层传递对象。然后行业开始考虑让开发人员的生活更轻松。他们开始通过某些框架来自动化映射过程,这些框架能够从数据库自动创建类,或者能够将表复制为类。所以,简而言之,这就是使用 Entity Framework 的目的,它可以自动生成模型代码,负责 SQL 查询,让开发人员的生活更轻松。即使您对数据库部分不太熟悉,Entity Framework 也会为您处理。让我们进入下一个讨论,我们如何在应用程序中使用 Entity Framework?在应用程序中实现 Entity Framework 有三种方法。我们将讨论这些方法,以便更好地理解本系列文章的后续内容。

代码优先方法

顾名思义,在这种方法中,我们首先编写代码来生成数据库,然后有一天,我们将运行这些代码在数据库服务器中看到数据库。以下是我们可以实现 Code First 方法的几个可能场景。

  • 您是一个硬核开发者,总是喜欢与代码玩耍,那么 Code First 方法非常适合您。
  • 如果您想在不了解太多 SQL 和 DBA 的情况下完全控制数据库设计。
  • 如果应用程序是全新的,并且没有现有的数据库。

所以,如果出现以上任何一种情况,您都可以放心地使用 Code First 方法。老实说,这种方法是三种方法中最受欢迎的一种,根据我个人的经验,我见过许多全新项目都采用了这种方法。

数据库优先 (Database First)

这是继 Code First 方法之后的下一个流行方法。Database First 方法最适合数据库已创建的情况,但这里还有一些其他可能性。

  • 当数据库已存在时,您只需要开发应用程序。
  • 当数据库结构非常复杂,需要 DBA 专业人员参与时。
  • 当您有兴趣同时处理应用程序的编码和数据库部分时。
  • 如果您想在 POCO 实体中添加额外功能,您必须修改 T4 模板或使用部分类。
  • 在这种方法中,手动更改数据库非常容易,因为它不直接依赖于代码。更改数据库,更新模型,工作顺利。

所以,这些是 Database First 方法适用的场景。

模型优先 (Model First)

我的个人经验表明,这种方法不如 Code First 和 Database First 流行的原因可能是,开发人员不想扮演设计者的角色。同样,以下是人们应该选择 Model First 方法的几个可能场景。

  • 当您想先创建数据模型并与非技术人员共享时。通过查看代码和表,非技术人员可能不理解,但她可能会理解实体的多彩表示。
  • 当您的应用程序是全新的,并且您不介意大量的自动生成代码,并且您知道在出现问题时在哪里进行调整。

无论如何,优点是,一旦设计了模型,它将同时创建您的类和数据库。好的,我们已经理解了 Entity Framework 的各种工作流程以及它们适用的场景。现在,在这篇文章中,我们将通过示例讨论 Code First 方法,并在连续的文章中深入探讨 Entity Framework。

需要指出的是,Code First 方法有两种方式可以实现

  1. 数据注解
  2. Fluent API

两者都流行且有用,但选择权在您。无论如何,我将在这里展示两种方式的 Code First 方法。所以,创建一个全新的应用程序,我选择了控制台应用程序进行演示,您可以自由选择任何其他类型。

使用数据注解的 Code First 方法

创建一个 `.cs` 文件并命名为 `person.cs`,然后将以下代码粘贴进去。由于这是数据注解方法,请不要忘记添加 `System.ComponentModel.DataAnnotation` 命名空间。

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp
{
    public class Person
    {
        [Key]
        public int Id{get;set;}
        [Required]
        public string name { get; set; }
        [Required]
        public string surname { get; set; }
    }

    public class Address
    {
        [Key]
        public int personAdressId { get; set; }
        public string address { get; set; }

        [MaxLength(6)]
        public string pin { get; set; }

        [ForeignKey("Person")]
        public int PersonId { get; set; }

        //Navigation property
        public virtual Person Person { get; set; }
    }

    public class personContext : DbContext
    {
        public personContext()
            : base("DBConnectionString")
        {
            //If model change, It will re-create new database.
            Database.SetInitializer<personContext>(new DropCreateDatabaseIfModelChanges<personContext>());
        }
        public DbSet<Person> person { get; set; }
        public DbSet<Address> Address { get; set; }
    }
}

如果您熟悉 MVC 中的数据注解,那么我相信您对这些属性很熟悉。`Key` 属性表示表的主键(我们稍后运行此脚本来创建表)。`Person` 和 `Address` 类非常容易理解。请记住,我们在 `Address` 类中设置了外键属性,它将指向 `Person` 类的主键。现在,让我们讨论上下文的创建部分。请看 `PersonContext` 类的定义。我们从 `DbContext` 类继承了它,在构造函数中,我们传递了“DBConnectionString”,我们将在 `web.config` 文件中稍后定义它。在构造函数中,我们指定要从头开始创建数据库。如果我的模型发生更改,这里是代码:`Database.SetInitializer(new DropCreateDatabaseIfModelChanges());`

现在,我们将在应用程序的 `web.config` 文件中指定连接字符串。

<connectionStrings>
    <add name="DBConnectionString" 
        connectionString="Data Source=SOURAV-PC;Initial Catalog=personDB;Integrated Security=true" 
        providerName="System.Data.SqlClient"/>
  </connectionStrings>

连接字符串非常简单。我没有包含用户名和密码,因为我希望使用 Windows 身份验证。如果需要,您可以提供数据库凭据。请注意,我提供的数据库名称是“personDB”,这意味着当我的代码创建数据库时,我期望的数据库名称就是这个。好了,我们已经完成了必要的设置。现在我们将运行代码来填充数据库。如果您像我一样使用控制台应用程序,只需修改 `Main()` 函数如下:

public static void Main(string[] args)
        {
            using (var ctx = new personContext())
            {
                ctx.Database.Create();
            }
        }

现在,让我们运行应用程序,等待奇迹发生。一旦它无异常地运行(希望如此),请检查您的数据库。这是我的:

您将看到上述数据库结构,其中会创建两个表并关联所有键。所以,这就是使用 Entity Framework 的 Code First 方法通过数据注解创建数据库的方法。

现在,我们将使用 Fluent API 实现相同的模型来创建数据库。请看 `person.cs` 文件中修改后的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp
{
    public class Person
    {
        public int Id{get;set;}

        public string name { get; set; }
        public string surname { get; set; }
    }

    public class Address
    {
        public int personAdressId { get; set; }
        public string address { get; set; }
        public string pin { get; set; }
        public int PersonId { get; set; }
        public virtual Person Person { get; set; }
    }

    public class personContext : DbContext
    {
        public personContext()
            : base("DBConnectionString")
        {
            //If model change, It will re-create new database.
            Database.SetInitializer<personContext>(new DropCreateDatabaseIfModelChanges<personContext>());
        }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            //Set primary key to Person table
            modelBuilder.Entity<Person>().HasKey(m => m.Id).Property(m => m.Id).IsRequired();
            //name fleld is required

            modelBuilder.Entity<Person>().Property(p => p.name).IsRequired();
            //surname is required
            modelBuilder.Entity<Person>().Property(p => p.surname).IsRequired();

            //set primary key to Address table
            modelBuilder.Entity<Address>().HasKey(m => m.personAdressId);

            //set max length property to 6 
            modelBuilder.Entity<Address>().Property(m => m.pin).HasMaxLength(6);

            //Set foreign key property
            modelBuilder.Entity<Address>().HasRequired(t => t.Person)
                .WithMany().HasForeignKey(t => t.PersonId);
        }
        public DbSet<Person> person { get; set; }
        public DbSet<Address> Address { get; set; }
    }
}

`Main()` 函数中的代码将保持不变,一旦我们运行应用程序,我们将获得相同的数据库结构。

总结

由于这是本系列的第一篇文章,我讨论了一些基本概念和示例。在未来的文章中,我们将重点关注 Code First 方法的各种主题。

© . All rights reserved.