Entity Framework(简称 EF)作为.NET 平台下的 ORM(对象关系映射)框架,极大地简化了数据库操作。本文将由浅入深,带您一步步了解 EF 实体数据模型的创建、配置、开发与使用,即使是新手也能快速上手。

一、EF 与 ADO.NET:为何选择 EF?

在介绍 EF 之前,我们先看看传统的数据访问方式与 EF 的区别:

  • ADO.NET 的局限:直接编写 SQL 语句操作数据库,需要手动处理类型转换、SQL 拼接等问题,不仅繁琐,还容易因 SQL 不规范导致错误或安全风险(如 SQL 注入)。
  • EF 的优势:通过实体数据模型(EDM)映射数据库结构,开发者只需操作 C# 对象,无需编写 SQL。EF 自动处理类型转换和数据库交互,大幅减少出错概率,同时支持 LINQ 查询,让数据操作更简洁。

二、EF 实体数据模型的核心:从数据库到对象的映射

EF 的核心是实体数据模型(EDM),它通过三个部分实现数据库与代码的映射:

  1. 存储模型(SSDL):描述数据库的物理结构(如表、字段、类型),对应底层数据库的真实结构。
  2. 概念模型(CSDL):定义 C# 中的实体类(如Student类),包含类的属性和关系,与数据库结构解耦。
  3. 映射(MSL):建立存储模型与概念模型的对应关系(如Student类的Name属性映射到数据库表的Name字段)。

这三层结构被存储在.edmx文件中,Visual Studio 的EF 设计器提供了可视化界面,方便开发者查看和编辑。

三、实战:创建第一个 EF 实体数据模型

下面以 “学生信息管理” 为例,从零开始创建 EF 模型并使用。

1. 准备工作:数据库与项目

  • 数据库:创建 SQL Server 数据库文件StudentInfo.mdf,包含一张Student表,结构如下:
字段名 类型 说明
Id int 主键(自增)
Name varchar(50) 学生姓名
Age int 年龄
Sex bit 性别(False 为男,True 为女)
Hobby varchar(50) 爱好
Birthday datetime 生日
  • 项目:创建 C# 控制台应用程序MyEFProject(框架选择.NET Framework 4.5 及以上)。

2. 创建 EF 实体数据模型

步骤 1:添加实体数据模型
  1. 在项目上右键 → 添加 → 新建项
  2. 选择 “ADO.NET 实体数据模型”,命名为StudentInfoModel.edmx,点击 “添加”;
  3. 在弹出的 “实体数据模型向导” 中,选择 “来自数据库的 EF 设计器”(即 Database First 模式),点击 “下一步”。
步骤 2:配置数据库连接
  1. 点击 “新建连接”,选择数据库文件StudentInfo.mdf,测试连接成功后,保存连接字符串(默认名称为StudentInfoEntities);
  2. 点击 “下一步”,选择要包含的数据库对象(这里勾选Student表),点击 “完成”。

此时,项目中会生成StudentInfoModel.edmx文件,双击打开可看到可视化的实体模型(Student类及其属性)。

3. 模型文件解析:.edmx 与自动生成的类

创建模型后,项目会自动生成以下关键文件:

  • StudentInfoModel.edmx:包含存储模型、概念模型和映射关系的 XML 文件。可右键选择 “打开方式 → XML 编辑器” 查看源码,其中:

    • <edmx:StorageModels>:存储模型,对应数据库表结构;
    • <edmx:ConceptualModels>:概念模型,对应 C# 实体类;
    • <edmx:Mappings>:映射关系,定义类属性与表字段的对应。
  • StudentInfoModel.Context.cs:继承自DbContext的类(如StudentInfoEntities),负责与数据库建立连接,提供数据操作入口。

    public partial class StudentInfoEntities : DbContext
    {
        public StudentInfoEntities() : base("name=StudentInfoEntities") { }
        public virtual DbSet<Student> Student { get; set; } // 映射Student表
    }
    
  • Student.cs:对应Student表的实体类,属性与表字段一一映射:

    public partial class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int? Age { get; set; } // 可空类型,对应数据库允许为NULL的字段
        public bool? Sex { get; set; }
        public string Hobby { get; set; }
        public DateTime? Birthday { get; set; }
    }
    

四、EF 数据操作实战:查询、新增、修改、删除

通过DbContextStudentInfoEntities)和DbSet<Student>,我们可以轻松实现数据库操作。

1. 查询数据

使用 LINQ 或 lambda 表达式查询Student表中的数据:

using System;
using System.Linq;

namespace MyEFProject
{
    class Program
    {
        static void Main(string[] args)
        {
            // 实例化DbContext,建立数据库连接
            using (var db = new StudentInfoEntities())
            {
                // 查询所有学生
                var allStudents = db.Student.ToList();
                Console.WriteLine("所有学生:");
                foreach (var stu in allStudents)
                {
                    Console.WriteLine($"ID: {stu.Id}, 姓名: {stu.Name}, 年龄: {stu.Age}");
                }

                // 条件查询:年龄大于16的学生
                var olderStudents = db.Student.Where(s => s.Age > 16).ToList();
                Console.WriteLine("\n年龄大于16的学生:");
                foreach (var stu in olderStudents)
                {
                    Console.WriteLine($"姓名: {stu.Name}, 年龄: {stu.Age}");
                }
            }
            Console.ReadKey();
        }
    }
}

2. 新增数据

通过DbSet.Add()添加新实体,再调用SaveChanges()提交到数据库:

using (var db = new StudentInfoEntities())
{
    // 创建新学生对象
    var newStu = new Student
    {
        Name = "张三",
        Age = 16,
        Sex = false,
        Hobby = "运动",
        Birthday = new DateTime(2007, 3, 15)
    };
    // 添加到DbSet
    db.Student.Add(newStu);
    // 提交保存
    db.SaveChanges();
    Console.WriteLine("新增成功,ID:" + newStu.Id); // 自增ID会自动返回
}

3. 修改数据

查询到实体后直接修改属性,再调用SaveChanges()

using (var db = new StudentInfoEntities())
{
    // 查询ID=1的学生
    var stu = db.Student.Find(1);
    if (stu != null)
    {
        // 修改属性
        stu.Age = 16;
        stu.Hobby = "阅读";
        // 提交修改
        db.SaveChanges();
        Console.WriteLine("修改成功");
    }
}

4. 删除数据

通过DbSet.Remove()删除实体,或直接调用db.Entry(stu).State = EntityState.Deleted

using (var db = new StudentInfoEntities())
{
    // 查询要删除的学生
    var stu = db.Student.Find(5);
    if (stu != null)
    {
        // 删除实体
        db.Student.Remove(stu);
        // 提交删除
        db.SaveChanges();
        Console.WriteLine("删除成功");
    }
}

五、进阶:模型配置与自定义

1. 通过设计器修改模型

双击StudentInfoModel.edmx打开设计器,可直接修改实体类或属性:

  • 重命名实体类或属性(如将Sex改为Gender);
  • 修改属性类型(如将Age的类型从int?改为int,需确保数据库字段不允许为 NULL);
  • 添加关联关系(如多个学生对应一个班级,可在设计器中添加Class实体并建立关联)。

2. 手动修改映射关系

若需自定义属性与字段的映射(如类属性UserName对应表字段Name),可通过 “映射详细信息” 窗口配置:

  1. 在设计器中选中实体类(如Student);
  2. 右键 → “映射详细信息”,在窗口中修改属性与字段的对应关系。

3. 利用特性或 Fluent API 配置

除了设计器,还可通过数据注解(特性)或 Fluent API 配置模型(需在OnModelCreating方法中实现):

// 数据注解示例(在Student类中)
public partial class Student
{
    [Key] // 标记主键
    public int Id { get; set; }

    [MaxLength(50)] // 限制长度
    [Required] // 不允许为NULL
    public string Name { get; set; }
}

// Fluent API示例(在StudentInfoEntities类中)
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Student>()
        .Property(s => s.Name)
        .HasMaxLength(50)
        .IsRequired();
}

六、总结

通过本文的介绍,我们掌握了 EF 实体数据模型的核心概念、创建流程及基本操作:

  1. 创建模型:通过 “来自数据库的 EF 设计器” 快速生成实体类和映射关系;
  2. 核心类DbContext负责数据库连接,DbSet对应数据表,实体类对应表记录;
  3. 数据操作:通过 LINQ 查询,结合Add/RemoveSaveChanges实现增删改查;
  4. 自定义配置:通过设计器、特性或 Fluent API 调整模型映射。

EF 的优势在于将数据库操作转化为对象操作,让开发者更专注于业务逻辑而非 SQL 编写。后续可进一步学习 Code First 模式(从代码生成数据库)和 EF Core(跨平台版本),提升数据访问层的灵活性。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐