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#通过app.manifest使程序以管理员身份运行

    下面是详细讲解“c#通过app.manifest使程序以管理员身份运行”的完整攻略: 1. 为何需要以管理员身份运行程序 在Windows系统中,一些操作需要管理员权限才能够执行,例如修改系统配置、创建和删除文件夹等等。对于这些需要管理员权限的操作,我们需要以管理员身份运行程序才能够正常执行。 2. 如何使用app.manifest来使程序以管理员身份运行 …

    C# 2023年6月1日
    00
  • 记一次 .NET 某外贸ERP 内存暴涨分析

    一:背景 1. 讲故事 上周有位朋友找到我,说他的 API 被多次调用后出现了内存暴涨,让我帮忙看下是怎么回事?看样子是有些担心,但也不是特别担心,那既然找到我,就给他分析一下吧。 二:WinDbg 分析 1. 到底是哪里的泄露 这也是我一直在训练营灌输的理念,一定要知道是哪一边的暴涨,否则很可能就南辕北辙了,使用 !address -summary 和 !…

    C# 2023年4月27日
    00
  • C#正则表达式之Regex类用法详解

    C#正则表达式之Regex类用法详解 正则表达式是一种强大的文本处理工具,常用于文本匹配、替换、过滤等操作。在C#中,我们可以使用Regex类来操作正则表达式。 Regex类的基本用法 Regex类提供了多个静态方法和实例方法,用于操作正则表达式。其中最常用的是Match和MatchCollection方法。 Match方法 Match方法用于查找第一个匹配…

    C# 2023年6月7日
    00
  • C#入门学习之集合、比较和转换

    C#是一门非常流行的面向对象编程语言,它的集合、比较和转换是编程中经常使用的基本概念。本篇攻略将详细讲解C#入门学习中集合、比较和转换的应用。 集合 集合是一个包含一组对象的数据结构,C#中的集合有很多种,如List、Dictionary、HashSet、Stack等等。在使用集合前需要先导入使用的命名空间。 List List是一个非常常用的集合类型,它可…

    C# 2023年5月15日
    00
  • C# 基于NAudio实现对Wav音频文件剪切(限PCM格式)

    下面是详细讲解如何使用C#和NAudio库来实现对Wav音频文件的剪切操作。 1. 准备工作 在开始之前,需要先准备好以下工作: 安装.NET开发环境(建议使用Visual Studio,下载地址:https://visualstudio.microsoft.com/zh-hans/downloads/); 安装NAudio库(可以使用NuGet进行安装,或…

    C# 2023年6月1日
    00
  • C#面向对象实现图书管理系统

    C#面向对象实现图书管理系统 系统简介 图书管理系统是一个用于管理图书馆和书店的软件系统。该系统可以实现对图书的入库、出库、借阅、归还等操作,同时还可以对图书进行查询、统计、打印等功能的实现。本文介绍使用C#面向对象的编程思想实现图书管理系统的完整攻略。 系统设计 系统结构设计 我们可以将图书管理系统分为以下几个模块: 用户管理模块:用于管理系统用户的登录、…

    C# 2023年5月31日
    00
  • asp.net(c#)开发中的文件上传组件uploadify的使用方法(带进度条)

    下面我将为您详细讲解asp.net(c#)开发中文件上传组件uploadify的使用方法(带进度条)的完整攻略。 一. 简介 uploadify是一款基于jQuery的文件上传插件,支持多文件上传,支持进度条显示。 二. 安装与引入 下载uploadify:在官网 https://www.uploadify.com/ 下载uploadify并解压文件。 引入…

    C# 2023年6月1日
    00
  • 解决C#中Linq GroupBy 和OrderBy失效的方法

    我将为你提供详细的攻略来解决C#中Linq GroupBy和OrderBy失效的问题。 问题描述 在使用Linq语句进行分组(GroupBy)和排序(OrderBy)操作时,有时会发现这些操作似乎没有生效,导致结果不符合预期。造成这种情况的原因是Linq语句中的默认比较方法(Comparer)可能无法正确处理对象的相等性或大小关系,从而导致分组和排序操作失败…

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