在Dapr中使用EF Core、Dapper等ORM框架操作数据库的方法及相关疑问
Great question! Let's break this down clearly—first off, DaprClient is absolutely not the only way to interact with databases in a Dapr-powered application. Dapr's state management is a useful abstraction, but you're totally free to use traditional ORMs like EF Core or micro-ORMs like Dapper directly with your database, which is actually a common approach to work around the limitations you've noticed in Dapr's built-in state management.
You can integrate EF Core into your Dapr application just like you would in a standard .NET project—no need to route database calls through Dapr's state store. Here's a quick example:
- Configure your DbContext in
Program.cs:
builder.Services.AddDbContext<AppDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
- Define your DbContext and entities:
public class AppDbContext : DbContext { public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { } public DbSet<Product> Products { get; set; } } public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } }
- Use EF Core in your controller/service:
[ApiController] [Route("api/products")] public class ProductsController : ControllerBase { private readonly AppDbContext _dbContext; public ProductsController(AppDbContext dbContext) { _dbContext = dbContext; } [HttpGet] public async Task<IActionResult> GetAllProducts() { var products = await _dbContext.Products.ToListAsync(); return Ok(products); } [HttpPost] public async Task<IActionResult> CreateProduct(Product product) { _dbContext.Products.Add(product); await _dbContext.SaveChangesAsync(); return CreatedAtAction(nameof(GetAllProducts), new { id = product.Id }, product); } }
This works exactly like a non-Dapr .NET app—you get full access to EF Core's features like migrations, query optimization, and change tracking, without being constrained by Dapr's state management limitations.
Dapper integrates just as seamlessly. You'll work directly with database connections and raw SQL, which is ideal if you need fine-grained control over queries. Here's how:
- Register your database connection in
Program.cs:
builder.Services.AddTransient<IDbConnection>(sp => new SqlConnection(builder.Configuration.GetConnectionString("DefaultConnection")));
- Use Dapper in your controller/service:
[ApiController] [Route("api/orders")] public class OrdersController : ControllerBase { private readonly IDbConnection _dbConnection; public OrdersController(IDbConnection dbConnection) { _dbConnection = dbConnection; } [HttpGet("{id}")] public async Task<IActionResult> GetOrderById(int id) { var order = await _dbConnection.QueryFirstOrDefaultAsync<Order>( "SELECT Id, CustomerName, TotalAmount FROM Orders WHERE Id = @Id", new { Id = id }); return order == null ? NotFound() : Ok(order); } [HttpPost] public async Task<IActionResult> CreateOrder(Order order) { var affectedRows = await _dbConnection.ExecuteAsync( "INSERT INTO Orders (CustomerName, TotalAmount) VALUES (@CustomerName, @TotalAmount)", order); return affectedRows > 0 ? Ok() : BadRequest("Failed to create order"); } } public class Order { public int Id { get; set; } public string CustomerName { get; set; } public decimal TotalAmount { get; set; } }
To help you decide which approach fits your use case:
- Use Dapr State Management if:
- You need to switch between state stores (e.g., SQL Server ↔ Redis) without rewriting data access code
- You require distributed transactions across multiple state stores
- You want built-in features like state TTL or optimistic concurrency
- Use EF Core/Dapper directly if:
- Your app relies on database-specific features (e.g., SQL Server stored procedures, PostgreSQL JSONB)
- You need advanced query capabilities or full control over data access logic
- You have existing ORM code you want to reuse without refactoring
内容的提问来源于stack exchange,提问作者sajad

