Dapper 是一個輕量、快速且簡單的 ORM 工具,與 Entity Framework 等傳統 ORM 相比,它不提供複雜的物件映射與 CRUD 生成,而是以 原生 SQL 命令 + 參數化查詢 的方式直接操作資料庫,具有以下優點:
效能高:無物件映射開銷,直接使用 ADO.NET。
語法簡潔:無冗長的 LINQ 語法,減少過多層次的抽象。
安全性強:自動處理參數化查詢,有效防止 SQL 注入。
易於測試與調試:SQL 語句明確可見,方便日誌與錯誤追蹤。
(跟 EF Core 相比之下,這比較好介紹)
在專案安裝以下工具,下面用 Cli 示意
// Dapper 元件
dotnet add package Dapper --version 2.1.66
// .Net SQL Client
dotnet add package Microsoft.Data.SqlClient --version 6.1.1
在 Program.cs
裡面註冊資料庫連線的 DI
// DefaultConnection 是放在 appsettings.json 裡面的資料庫連線字串
builder.Services.AddScoped<IDbConnection>(sp => new Microsoft.Data.SqlClient.SqlConnection(builder.Configuration.GetConnectionString("DefaultConnection")));
把之前使用的 UserRepository.cs
修改成真的跟資料庫使用
public interface IUserRepository
{
Task<User?> FindUser(string userName);
}
/// <summary>
/// 資料庫對應物件
/// </summary>
public class User
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
}
public class UserRepository : IUserRepository
{
private readonly IDbConnection _connection;
public UserRepository(IDbConnection connection)
{
_connection = connection;
}
public async Task<User?> FindUser(string userId)
{
var sql = "SELECT Id, Name, Price, Category FROM User WHERE Id = @Id";
return await _connection.QueryFirstOrDefaultAsync<User>(sql, new { Id = userId });
}
}
調整 UserService.cs
public class UserService : MyGrpcServer.UserService.UserServiceBase
{
private readonly IUserRepository _userRepository;
public UserService(IUserRepository userRepository)
{
_userRepository = userRepository;
}
public override async Task<GetUserResponse> GetUser(GetUserRequest request, ServerCallContext context)
{
var res = await _userRepository.FindUser(request.UserId);
if (res is null)
{
throw new RpcException(new Grpc.Core.Status(StatusCode.NotFound, "User not found"));
}
return new GetUserResponse()
{
User = new User { Name = res.Name},
Status = Status.Active
};
}
}