Entity Framework代码优先(Code First)模式

下面是Entity Framework代码优先(Code First)模式的完整攻略,包括定义数据模型、创建数据库、数据存取操作等内容。

什么是代码优先(Code First)模式

Entity Framework是微软推出的一个ORM(对象关系映射)框架,用于简化应用程序与数据库之间的访问。Entity Framework有三种模式:数据库优先(DataBase First)、模型优先(Model First)和代码优先(Code First)。

数据库优先的做法是先设计好数据库表结构,然后通过Entity Framework去生成相应的数据模型;模型优先就是通过给定模型(EDMX)去创建对应的数据表。而代码优先就是通过写代码定义数据模型,然后再通过EF去创建相应的数据库表结构。

相较于其他模式,代码优先具有以下优势:

  1. 代码优先可以方便快捷地定义实体类和关系,很好地支持敏捷开发等前端代码开发模式。
  2. 实体数据的模型完全独立于数据库,只需通过API方法即可轻松实现数据库的操作和管理,使工作更加方便、高效。
  3. 因为使用了代码优先,开发人员将与实体模型直接打交道,而不必关注数据库底层结构,也可以通过反向工程来生成代码库,减少手工工作量。

如何使用代码优先模式

使用代码优先需要遵循以下步骤:

1. 定义数据模型

使用代码优先就是先使用 POCO(Plain Old CLR Object),通过定义实体类和DbContext来确定数据模型与关系。实体类就是代表一个数据库表的类,而DbContext则是代表整个数据库。在定义实体类时,需要指定它们如何映射到数据库,例如:

public class MyEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
}

2. 创建数据库

在定义好实体类和上下文(DbContext)后,需要在应用程序启动时创建数据库。该操作称为“代码第一次迁移”。

在 Visual Studio 中打开如下命令行窗口:

PM> enable-migrations

执行上面的命令之后,一个 Migrations 文件夹将会自动创建。

此时,可以执行如下命令来创建数据库:

PM> update-database

此时,如果之前没有定义过数据库,则会创建一个新的数据库。如果定义过,则会更新已经存在的数据库。如果修改了字段等模型的定义,则需要再次执行update-database。

3. 数据存取操作

在 DbContext 中可以定义 DbSet 属性,它表示可以查询的实体集合。可以使用调用 DbSet 的 LINQ 查询来进行各种数据操作,例如:

public class MyDbContext : DbContext
{
    public MyDbContext(string connectionString) : base(connectionString)
    {
    }

    public DbSet<MyEntity> MyEntities { get; set; }
}

// 在其他代码中
using (var context = new MyDbContext(connectionString)) {
    // 添加一个 MyEntity 实例
    var entity = new MyEntity() { Name = "My Entity" };
    context.MyEntities.Add(entity);

    // 提交数据修改
    context.SaveChanges();
}

两个示例说明

下面,我将通过两个示例来说明如何在代码优先模式下操作数据库。

示例1:创建用户表

public class User
{
    [Key] // 主键自增长
    public int Id { get; set; }

    [Required] // 不允许空值
    public string Name { get; set; }

    [EmailAddress] // 只允许电子邮件格式
    public string Email { get; set; }
}

// DbContext
public class MyDbContext : DbContext
{
    public MyDbContext(string connectionString) : base(connectionString) { }

    public DbSet<User> Users { get; set; }
}

定义好了User类和MyDbContext这个上下文对象之后,我们就可以通过一些方法增删查改User对象了

using (var context = new MyDbContext("your connection string")) {
    // 添加一个用户
    var user = new User { Name = "Demo", Email = "demo@example.com" };
    context.Users.Add(user);
    context.SaveChanges();

    // 查询所有用户
    var users = context.Users.ToList();

    // 修改用户信息
    user.Name = "Updated Name";
    user.Email = "Updated Email";
    context.SaveChanges();

    // 删除一个用户
    context.Users.Remove(user);
    context.SaveChanges();
}

示例2: 创建多个表并设置外键关系

// 创建一个课程数据模型
public class Course
{
    [Key]
    public int Id { get; set; }

    [Required]
    public string Name { get; set; }

    public virtual ICollection<Enrollment> Enrollments { get; set; }
}

// 创建一个学生数据模型
public class Student
{
    [Key]
    public int Id { get; set; }

    [Required]
    public string Name { get; set; }

    [EmailAddress]
    public string Email { get; set; }

    public virtual ICollection<Enrollment> Enrollments { get; set; }
}

// 录取数据模型
public class Enrollment
{
    [Key]
    public int Id { get; set; }

    [Required]
    public int StudentId { get; set; }

    [Required]
    public int CourseId { get; set; }

    [ForeignKey("StudentId")]
    public virtual Student Student { get; set; }

    [ForeignKey("CourseId")]
    public virtual Course Course { get; set; }

    public int Score { get; set; }
}

// DbContext
public class MyDbContext : DbContext
{
    public MyDbContext(string connectionString) : base(connectionString) { }

    public DbSet<Student> Students { get; set; }
    public DbSet<Course> Courses { get; set; }
    public DbSet<Enrollment> Enrollments { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        // 配置外键关系
        modelBuilder.Entity<Enrollment>()
            .HasRequired(e => e.Student)
            .WithMany(s => s.Enrollments)
            .HasForeignKey(e => e.StudentId);

        modelBuilder.Entity<Enrollment>()
            .HasRequired(e => e.Course)
            .WithMany(c => c.Enrollments)
            .HasForeignKey(e => e.CourseId);
    }
}

上面代码定义了三个数据模型,Student 和 Course 实体类表示学生和课程,Enrollment 实体类表示学生选修课程,Enrollment 中的StudentId 和CourseId 为外键,指向Student 和Course 实体类中的Id。

在 DbContext 中,我们可以定义 DbSet 属性,表示要操作的实体集合。一个实体类通常需要映射到一个表中,这里Student 实体类映射到Students表中,Course 实体类映射到Course表中,Enrollment 实体类映射到Enrollments表中。

当Enrollment 实体类映射到数据库表结构中时,需要在 DbContext 中配置外键关系,这个配置使用OnModelCreating方法执行。

然后我们就可以通过一些方法增删查改User 对象:

using (var context = new MyDbContext("your connection string")) {
    // 创建一个课程
    var course = new Course { Name = "Mathematics" };
    context.Courses.Add(course);
    context.SaveChanges();

    // 创建一个学生
    var student = new Student { Name = "Bob", Email = "bob@example.com" };
    context.Students.Add(student);
    context.SaveChanges();

    // 建立学生和课程之间的联系
    var enrollment = new Enrollment { CourseId = course.Id, StudentId = student.Id };
    context.Enrollments.Add(enrollment);
    context.SaveChanges();

    // 查询选修这门课程的所有学生
    var studentsInCourse = course.Enrollments.Select(e => e.Student).ToList();

    // 查询Bob选修的所有课程
    var bobsEnrollments = student.Enrollments.Select(e => e.Course).ToList();
}

以上就是两个示例,说明如何使用代码优先模式创建数据库表,定义关系以及进行数据库操作。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Entity Framework代码优先(Code First)模式 - Python技术站

(0)
上一篇 2023年6月3日
下一篇 2023年6月3日

相关文章

  • 深入分析c# 继承

    深入分析c# 继承 继承的概念 继承是面向对象编程的一种重要特性,指在一个现有类的基础上创建一个新类。新类继承了现有类的所有属性和方法,在此基础上可以添加新属性和方法,或者重新定义现有方法。被继承的现有类称为父类或基类,新创建的类称为子类或派生类。 继承的语法 c#的继承语法是使用冒号将子类与父类连接起来: class ChildClass : Parent…

    C# 2023年6月7日
    00
  • C#中的事件介绍

    C#中的事件介绍 在C#中,事件是一种典型的观察者设计模式的应用。事件机制使得对象间的协作变得更加松散,同时也易于扩展。本篇文章将介绍C#中的事件,包括事件的定义、事件的注册和注销以及如何触发事件。 定义事件 在C#中,事件是一种特殊的委托,它定义了一个回调函数的集合。定义事件的方式是使用event关键字,语法如下: public event EventHa…

    C# 2023年5月31日
    00
  • .NET Core配置多环境的方法步骤

    .NET Core 配置多环境的方法步骤 在 .NET Core 中,我们可以使用多环境配置来管理不同环境下的应用程序配置。本攻略将介绍如何在 .NET Core 中配置多环境。 步骤 以下是在 .NET Core 中配置多环境的步骤: 创建 appsettings.json 文件。 在项目根目录下创建 appsettings.json 文件,并添加以下内容…

    C# 2023年5月17日
    00
  • asp.net(c#)下各种进制间的轻松转换(2进制、8进制、10进制、16进制)

    ASP.NET(C#)中进制转换的攻略 前言 在开发过程中,我们经常会用到不同进制的表示方式。在ASP.NET项目中,我们可以轻松的进行不同进制之间的转换。本文将介绍ASP.NET(C#)中各种进制间的轻松转换方法。 进制介绍 在计算机科学中,所有数据都是以 0 和 1 的二进制数表示的。但是,二进制数字对于人们来说并不直观,因此我们通常使用其他进制表示数据…

    C# 2023年6月3日
    00
  • C#6.0中10大新特性的应用和总结

    C#6.0中10大新特性的应用和总结 随着 C# 6.0 的发布,微软在语言上增加了 10 多项特性,为 C# 开发带来了更快速和简单的编写代码方式。下面将介绍 C#6.0 的 10 大新特性及其应用。 1. using static 在以前的版本中,需要使用类的全限定名称才能调用静态成员,如 Console.WriteLine 或 Math.PI。而在 C…

    C# 2023年5月14日
    00
  • C#使用Task实现执行并行任务的原理的示例详解

    下面就来详细讲解如何使用C#的Task库实现并行执行任务的原理及示例。 什么是Task Task是.NET Framework 4.5及以上版本中新增的一个库,它的主要作用是提供一种方便、高效的方式来管理并发和异步编程相关的任务。相比较于自行利用Thread和ThreadPool管理线程,使用Task可以更方便地控制异步任务,并且能够支持更多种的异步模型。 …

    C# 2023年5月15日
    00
  • C#中的图像Image类与打印Printing类用法

    C#中的图像Image类与打印Printing类用法攻略 概述 在C#中,Image类和Printing类都是常用的操作图像和打印的类,它们提供了丰富的方法和属性,可以方便地实现各种图像的处理和打印。 Image类:Image类是用于操作图像的类,可以将图像加载到内存中、进行绘制、剪切等操作。 Printing类:Printing类是用于打印的类,可以控制打…

    C# 2023年6月8日
    00
  • C#利用Task实现任务超时多任务一起执行的方法

    下面我将为你详细讲解“C#利用Task实现任务超时多任务一起执行的方法”的完整攻略。 1. 使用Task.WaitAny方法实现超时控制 在C#中,使用Task可以很方便地实现多任务并行执行,但是如果需要控制任务的执行时间,避免超时等问题,则需要使用Task.WaitAny方法。具体步骤如下: 步骤1:启动多个任务 首先,我们需要启动多个任务,让它们并行执行…

    C# 2023年6月6日
    00
合作推广
合作推广
分享本页
返回顶部