.net MVC 连接数据本地数据库三种方法总结
《.NET MVC 连接本地数据库三种方法总结》
在.NET MVC开发中,连接本地数据库是构建数据驱动型应用的基础。无论是SQL Server、SQLite还是MySQL等本地数据库,掌握多种连接方式不仅能提升开发效率,还能增强代码的灵活性和可维护性。本文将详细介绍三种常见的.NET MVC连接本地数据库的方法,包括Entity Framework Core(EF Core)、ADO.NET原生连接以及Dapper轻量级ORM,帮助开发者根据项目需求选择合适的方案。
一、方法一:使用Entity Framework Core(EF Core)
EF Core是微软官方推荐的ORM框架,它通过LINQ查询和强类型实体模型简化了数据库操作,支持迁移(Migration)和代码优先(Code-First)开发模式,尤其适合中大型项目。
1.1 安装必要的NuGet包
在.NET MVC项目中,首先需要安装EF Core的核心包和对应数据库提供程序。例如,连接SQL Server时需安装以下包:
Install-Package Microsoft.EntityFrameworkCore
Install-Package Microsoft.EntityFrameworkCore.SqlServer
1.2 创建DbContext和实体类
定义实体类(如`User`)和继承自`DbContext`的上下文类(如`AppDbContext`):
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
public class AppDbContext : DbContext
{
public DbSet Users { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=MyDb;Trusted_Connection=True;");
}
}
1.3 配置依赖注入(DI)
在`Startup.cs`中注册`DbContext`:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddControllersWithViews();
}
并在`appsettings.json`中配置连接字符串:
{
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=MyDb;Trusted_Connection=True;"
}
}
1.4 使用EF Core进行CRUD操作
在控制器中注入`AppDbContext`并操作数据:
public class UserController : Controller
{
private readonly AppDbContext _context;
public UserController(AppDbContext context)
{
_context = context;
}
public IActionResult Index()
{
var users = _context.Users.ToList();
return View(users);
}
[HttpPost]
public IActionResult Create(User user)
{
_context.Users.Add(user);
_context.SaveChanges();
return RedirectToAction("Index");
}
}
1.5 代码迁移与数据库更新
使用EF Core的迁移功能管理数据库结构变更:
Add-Migration InitialCreate
Update-Database
二、方法二:使用ADO.NET原生连接
ADO.NET是.NET Framework中直接操作数据库的底层API,适合需要精细控制SQL语句或性能要求极高的场景。虽然代码量较大,但灵活性高。
2.1 配置连接字符串
在`Web.config`或`appsettings.json`中定义连接字符串:
{
"ConnectionStrings": {
"LocalDb": "Data Source=(localdb)\\mssqllocaldb;Initial Catalog=MyDb;Integrated Security=True;"
}
}
2.2 创建数据库帮助类
封装一个`DbHelper`类来管理连接和命令:
public class DbHelper
{
private readonly string _connectionString;
public DbHelper(IConfiguration configuration)
{
_connectionString = configuration.GetConnectionString("LocalDb");
}
public SqlConnection GetConnection()
{
return new SqlConnection(_connectionString);
}
public DataTable ExecuteQuery(string sql, params SqlParameter[] parameters)
{
using (var connection = GetConnection())
{
using (var command = new SqlCommand(sql, connection))
{
command.Parameters.AddRange(parameters);
var adapter = new SqlDataAdapter(command);
var dataTable = new DataTable();
adapter.Fill(dataTable);
return dataTable;
}
}
}
}
2.3 在控制器中使用ADO.NET
查询数据并绑定到视图:
public class UserController : Controller
{
private readonly DbHelper _dbHelper;
public UserController(IConfiguration configuration)
{
_dbHelper = new DbHelper(configuration);
}
public IActionResult Index()
{
var sql = "SELECT * FROM Users";
var users = _dbHelper.ExecuteQuery(sql);
return View(users);
}
[HttpPost]
public IActionResult Create(string name, string email)
{
var sql = "INSERT INTO Users (Name, Email) VALUES (@Name, @Email)";
var parameters = new[]
{
new SqlParameter("@Name", name),
new SqlParameter("@Email", email)
};
_dbHelper.ExecuteQuery(sql, parameters);
return RedirectToAction("Index");
}
}
2.4 事务处理
使用`SqlTransaction`确保数据一致性:
public void TransferFunds(int fromAccountId, int toAccountId, decimal amount)
{
using (var connection = _dbHelper.GetConnection())
{
connection.Open();
using (var transaction = connection.BeginTransaction())
{
try
{
var sql1 = "UPDATE Accounts SET Balance = Balance - @Amount WHERE Id = @FromId";
var cmd1 = new SqlCommand(sql1, connection, transaction);
cmd1.Parameters.AddWithValue("@Amount", amount);
cmd1.Parameters.AddWithValue("@FromId", fromAccountId);
cmd1.ExecuteNonQuery();
var sql2 = "UPDATE Accounts SET Balance = Balance + @Amount WHERE Id = @ToId";
var cmd2 = new SqlCommand(sql2, connection, transaction);
cmd2.Parameters.AddWithValue("@Amount", amount);
cmd2.Parameters.AddWithValue("@ToId", toAccountId);
cmd2.ExecuteNonQuery();
transaction.Commit();
}
catch
{
transaction.Rollback();
throw;
}
}
}
}
三、方法三:使用Dapper轻量级ORM
Dapper是一个微型的ORM框架,由Stack Overflow团队开发,它通过扩展`IDbConnection`提供高效的映射功能,性能接近原生ADO.NET,同时减少了重复代码。
3.1 安装Dapper NuGet包
Install-Package Dapper
3.2 创建数据访问层
封装一个`UserRepository`类:
public class UserRepository
{
private readonly string _connectionString;
public UserRepository(IConfiguration configuration)
{
_connectionString = configuration.GetConnectionString("LocalDb");
}
public IEnumerable GetAllUsers()
{
using (var connection = new SqlConnection(_connectionString))
{
return connection.Query("SELECT * FROM Users");
}
}
public User GetUserById(int id)
{
using (var connection = new SqlConnection(_connectionString))
{
return connection.QueryFirstOrDefault(
"SELECT * FROM Users WHERE Id = @Id",
new { Id = id });
}
}
public int AddUser(User user)
{
using (var connection = new SqlConnection(_connectionString))
{
var sql = "INSERT INTO Users (Name, Email) VALUES (@Name, @Email); SELECT CAST(SCOPE_IDENTITY() AS INT)";
return connection.QuerySingle(sql, user);
}
}
}
3.3 在控制器中使用Dapper
public class UserController : Controller
{
private readonly UserRepository _userRepository;
public UserController(IConfiguration configuration)
{
_userRepository = new UserRepository(configuration);
}
public IActionResult Index()
{
var users = _userRepository.GetAllUsers();
return View(users);
}
[HttpPost]
public IActionResult Create(User user)
{
var userId = _userRepository.AddUser(user);
return RedirectToAction("Details", new { id = userId });
}
}
3.4 存储过程与多映射
调用存储过程并映射多个结果集:
public class OrderRepository
{
public (Order Order, List Items) GetOrderWithItems(int orderId)
{
using (var connection = new SqlConnection(_connectionString))
{
var sql = "EXEC GetOrderWithItems @OrderId";
using (var multi = connection.QueryMultiple(sql, new { OrderId = orderId }))
{
var order = multi.Read().First();
var items = multi.Read().ToList();
return (order, items);
}
}
}
}
四、三种方法对比与选择建议
1. **EF Core**:适合需要快速开发、支持迁移和LINQ查询的中大型项目。优点是代码简洁、支持懒加载和导航属性;缺点是性能略低于原生SQL,启动时加载较慢。
2. **ADO.NET**:适合对性能要求极高或需要精细控制SQL的场景。优点是直接操作数据库,无额外开销;缺点是代码量较大,需手动处理参数和异常。
3. **Dapper**:适合中小型项目或需要平衡性能与开发效率的场景。优点是轻量级、高性能,接近原生SQL;缺点是缺乏EF Core的高级功能(如迁移、变更跟踪)。
五、常见问题与解决方案
1. **连接字符串配置错误**:确保连接字符串中的服务器名称、数据库名称和认证方式正确。对于LocalDB,使用`(localdb)\\mssqllocaldb`。
2. **EF Core迁移失败**:检查`DbContext`是否正确配置,并确保项目引用了对应的数据库提供程序包。
3. **Dapper参数映射问题**:确保参数名称与SQL语句中的占位符一致,或使用匿名对象传递参数。
4. **并发冲突**:在EF Core中使用`ConcurrencyCheck`特性或乐观并发控制,在ADO.NET中手动实现版本号或时间戳。
六、总结
.NET MVC连接本地数据库的三种方法各有优劣,开发者应根据项目规模、性能需求和维护成本综合选择。EF Core提供了最高级别的抽象和开发效率,ADO.NET提供了最大的控制权,而Dapper则在两者之间取得了平衡。掌握这三种方法将显著提升.NET MVC开发者的数据库操作能力。
关键词:.NET MVC、本地数据库连接、Entity Framework Core、ADO.NET、Dapper、ORM、SQL Server、数据库迁移、依赖注入、存储过程
简介:本文详细介绍了.NET MVC中连接本地数据库的三种方法:Entity Framework Core(EF Core)、ADO.NET原生连接和Dapper轻量级ORM。通过代码示例和对比分析,帮助开发者根据项目需求选择合适的数据库访问方案,并提供了常见问题的解决方案。