[ASP.NET MVC 小牛之路]06 - 使用 Entity Framework 完全指南
数据驱动应用开发的核心利器:掌握Entity Framework,让ASP.NET MVC的数据操作优雅高效
目录#
- Entity Framework概述
- Entity Framework开发模式
- 项目集成实战
- CRUD操作指南
- 数据注解与配置
- 迁移管理
- 性能优化策略
- 最佳实践
- 总结
- 参考资料
Entity Framework概述#
Entity Framework(EF)是微软推出的对象关系映射(ORM)框架,作为.NET生态系统中的数据访问核心技术。在ASP.NET MVC中使用EF有诸多优势:
- 数据库无关性:支持SQL Server、MySQL、SQLite等多种数据库
- 强类型LINQ查询:编译时检查取代SQL字符串拼接
- 变更跟踪:自动管理实体状态变化
- 开发效率:减少70%以上的数据访问层代码量
最新稳定版Entity Framework 6.x(支持.NET Framework)和Entity Framework Core(跨平台)都是MVC开发的理想选择
graph LR
A[ASP.NET MVC Controller] --> B[Entity Framework]
B --> C[Database]
B --> D[SQL Server]
B --> E[MySQL]
B --> F[PostgreSQL]Entity Framework开发模式#
1. Database First#
适用场景:已有数据库结构,需要快速生成模型
// 自动生成的实体类
[Table("Customers")]
public partial class Customer
{
[Key]
public int CustomerID { get; set; }
[Required]
[StringLength(50)]
public string Name { get; set; }
}2. Model First#
在设计器中创建EDMX模型,同步生成数据库和代码
3. Code First(推荐)#
现代开发的首选方式,通过C#类定义模型:
public class Product
{
public int ProductID { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public DateTime CreatedDate { get; set; } = DateTime.Now;
}项目集成实战#
步骤1:安装NuGet包#
Install-Package EntityFramework步骤2:创建DbContext#
public class AppDbContext : DbContext
{
public AppDbContext() : base("name=DefaultConnection") { }
public DbSet<Product> Products { get; set; }
public DbSet<Category> Categories { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Fluent API配置
modelBuilder.Entity<Product>()
.HasRequired(p => p.Category)
.WithMany(c => c.Products)
.HasForeignKey(p => p.CategoryId);
}
}步骤3:配置连接字符串#
Web.config配置:
<connectionStrings>
<add name="DefaultConnection"
connectionString="Server=.;Database=MvcDemo;User Id=sa;Password=123;"
providerName="System.Data.SqlClient"/>
</connectionStrings>CRUD操作指南#
创建记录#
using(var db = new AppDbContext())
{
var newProduct = new Product { Name = "iPad", Price = 2999 };
db.Products.Add(newProduct);
db.SaveChanges(); // 返回受影响行数
}查询记录#
基本LINQ查询:
// 获取所有价格大于1000的产品
var expensiveProducts = db.Products
.Where(p => p.Price > 1000)
.OrderByDescending(p => p.Price)
.ToList();带关联查询:
var productsWithCategory = db.Products
.Include(p => p.Category) // 预加载关联数据
.Select(p => new {
p.Name,
CategoryName = p.Category.Name
}).ToList();更新记录#
var product = db.Products.Find(1);
if(product != null)
{
product.Price = 2599;
db.SaveChanges();
}删除记录#
var product = db.Products.FirstOrDefault(p => p.Name == "iPod");
if(product != null)
{
db.Products.Remove(product);
db.SaveChanges();
}数据注解与配置#
数据注解方式#
public class User
{
[Key]
public int UserId { get; set; }
[Required]
[StringLength(100)]
public string Email { get; set; }
[Column("BirthDate")]
public DateTime DateOfBirth { get; set; }
}Fluent API(更强大的配置)#
在OnModelCreating中配置:
modelBuilder.Entity<User>()
.Property(u => u.Email)
.IsRequired()
.HasMaxLength(100);
modelBuilder.Entity<User>()
.Ignore(u => u.TemporaryCode); // 排除属性迁移管理#
Code First的核心优势 - 优雅的数据库版本控制
启用迁移#
Enable-Migrations添加迁移#
Add-Migration AddUserTable生成的迁移文件:
public partial class AddUserTable : DbMigration
{
public override void Up()
{
CreateTable("Users",
c => new {
UserId = c.Int(identity: true),
Email = c.String(maxLength: 100),
BirthDate = c.DateTime()
})
.PrimaryKey(t => t.UserId);
}
public override void Down()
{
DropTable("Users");
}
}更新数据库#
Update-Database性能优化策略#
1. 禁用延迟加载#
public class AppDbContext : DbContext
{
public AppDbContext()
{
this.Configuration.LazyLoadingEnabled = false;
}
}2. 使用异步操作#
public async Task<List<Product>> GetProductsAsync()
{
return await db.Products.ToListAsync();
}3. 避免N+1查询#
使用Include预加载关联数据
// 错误方式 - N+1查询问题
foreach(var category in db.Categories)
{
foreach(var product in category.Products) // 每次循环查询数据库
{...}
}
// 正确方式
var categories = db.Categories.Include(c => c.Products).ToList();4. 批量操作优化#
使用AddRange代替循环Add
// 低效
foreach(var item in list)
{
db.Products.Add(item);
}
// 高效
db.Products.AddRange(productList);最佳实践#
-
DbContext生命周期
控制为Per Request(在ASP.NET MVC中推荐使用DI注入) -
仓储模式应用
public interface IProductRepository { IEnumerable<Product> GetFeaturedProducts(); } public class ProductRepository : IProductRepository { private AppDbContext _context; public ProductRepository(AppDbContext context) { _context = context; } } -
连接字符串加密
<connectionStrings configProtectionProvider="RsaProtectedConfigurationProvider"> <EncryptedData>...</EncryptedData> </connectionStrings> -
敏感数据日志过滤
dbContext.Database.Log = log => { if(log.Contains("Password")) Debug.WriteLine("-- SECRET DATA --"); else Debug.WriteLine(log); }; -
分离DbContext配置
public class ProductConfiguration : EntityTypeConfiguration<Product> { public ProductConfiguration() { Property(p => p.Name).IsRequired().HasMaxLength(200); } } // 在DbContext中注册 protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Configurations.Add(new ProductConfiguration()); }
总结#
Entity Framework在ASP.NET MVC开发中扮演着关键角色:
- 掌握Code First模式可提升开发效率
- 迁移机制实现优雅的数据库版本控制
- LINQ语法提供强类型查询能力
- 合理的性能优化策略保障应用高效运行
- 遵循最佳实践构建可维护的架构
关键认知转变:不再思考SQL语句编写,而是专注于业务对象操作
参考资料#
- 微软官方EF文档
- Entity Framework教程 by EntityFrameworkTutorial
- 《Entity Framework in Action, 2nd Edition》- Jon P Smith
- EF Core性能优化指南
- Dapper vs EF Core性能对比