C Sharp EF 代码优先(Code First)
外观
C# EF 代码优先(Code First)[编辑 | 编辑源代码]
Entity Framework (EF) 代码优先(Code First)是微软推出的一种面向对象的数据库开发方法,允许开发者通过定义C#类来创建数据库结构,而无需手动编写SQL脚本或使用数据库设计工具。它属于ORM(对象关系映射)技术的一部分,适用于需要快速开发、灵活调整数据模型的场景。
核心概念[编辑 | 编辑源代码]
代码优先方法的核心思想是:
- 开发者首先编写领域模型(POCO类)
- EF根据这些类自动生成数据库架构
- 支持数据库迁移(Migrations)来同步模型变更
与传统方法的对比[编辑 | 编辑源代码]
ADO.NET / 数据库优先 | EF 代码优先 |
---|---|
先编写C#类 | |
自动生成SQL | |
修改类后运行迁移命令 |
基础实现步骤[编辑 | 编辑源代码]
以下是实现EF代码优先的基本流程:
1. 安装NuGet包[编辑 | 编辑源代码]
Install-Package EntityFramework
2. 创建领域模型[编辑 | 编辑源代码]
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
// 导航属性
public virtual ICollection<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
// 外键
public int BlogId { get; set; }
// 导航属性
public virtual Blog Blog { get; set; }
}
3. 创建DbContext[编辑 | 编辑源代码]
public class BlogContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
}
4. 配置连接字符串[编辑 | 编辑源代码]
在App.config或Web.config中添加:
<connectionStrings>
<add name="BlogContext"
connectionString="Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=BlogDB;Integrated Security=True"
providerName="System.Data.SqlClient"/>
</connectionStrings>
数据库迁移[编辑 | 编辑源代码]
代码优先的强大功能之一是支持数据库架构的版本控制:
启用迁移[编辑 | 编辑源代码]
Enable-Migrations
创建迁移[编辑 | 编辑源代码]
Add-Migration InitialCreate
更新数据库[编辑 | 编辑源代码]
Update-Database
高级配置[编辑 | 编辑源代码]
数据注解[编辑 | 编辑源代码]
可以通过特性配置模型:
[Table("BlogArticles")]
public class Blog
{
[Key]
public int PrimaryKey { get; set; }
[Required]
[MaxLength(100)]
public string Name { get; set; }
}
Fluent API[编辑 | 编辑源代码]
在DbContext中重写OnModelCreating方法:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property(b => b.Name)
.IsRequired()
.HasMaxLength(100);
}
实际应用案例[编辑 | 编辑源代码]
场景:开发一个简单的博客系统
模型定义[编辑 | 编辑源代码]
public class Author
{
public int AuthorId { get; set; }
public string Name { get; set; }
public ICollection<Blog> Blogs { get; set; }
}
// 扩展之前的Blog类
public class Blog
{
//...其他属性
public int AuthorId { get; set; }
public Author Author { get; set; }
}
数据库查询示例[编辑 | 编辑源代码]
using (var context = new BlogContext())
{
// 添加数据
var author = new Author { Name = "张三" };
context.Authors.Add(author);
var blog = new Blog {
Name = "EF教程",
Author = author
};
context.Blogs.Add(blog);
context.SaveChanges();
// 查询数据
var blogsWithAuthors = context.Blogs
.Include(b => b.Author)
.ToList();
}
性能优化[编辑 | 编辑源代码]
- 延迟加载:使用virtual关键字标记导航属性
- 预先加载:使用Include方法
- 批量操作:使用AddRange/RemoveRange
批量插入示例[编辑 | 编辑源代码]
var blogs = new List<Blog>();
for (int i = 0; i < 1000; i++)
{
blogs.Add(new Blog { Name = $"Blog {i}" });
}
context.Blogs.AddRange(blogs);
context.SaveChanges();
架构图[编辑 | 编辑源代码]
数学表示[编辑 | 编辑源代码]
关系模型可以表示为: 外键约束:
常见问题[编辑 | 编辑源代码]
Q: 如何处理现有数据库? A: 使用逆向工程工具"EF Power Tools"或Scaffold-DbContext命令
Q: 如何执行原始SQL? A: 使用DbContext.Database.SqlQuery方法
Q: 并发冲突如何解决? A: 使用[ConcurrencyCheck]特性或配置RowVersion
最佳实践[编辑 | 编辑源代码]
- 保持POCO类简单
- 将配置分离到单独的类
- 使用仓储模式抽象DbContext
- 为频繁查询添加适当的索引
总结[编辑 | 编辑源代码]
EF代码优先提供了一种高效的数据库开发方式,特别适合:
- 快速原型开发
- 领域驱动设计(DDD)项目
- 需要频繁修改数据模型的场景
通过合理使用迁移、配置和优化技术,可以构建出既灵活又高性能的数据访问层。