Dapper in C#:高效的数据访问

作者:微信公众号:【架构师老卢】
2-18 15:11
31

概述:您好,管理数据访问是构建高效且安全的应用程序的关键组成部分。虽然实体框架 (EF) 是广泛使用的 .NET ORM,但 Dapper 已成为一种流行的轻量级替代方案。本文将探讨 Dapper 是什么、它的好处和实际用法。我们还将比较 Dapper 和 Entity Framework,并讨论何时选择它们。什么是Dapper?Dapper 是用于扩展 IDbConnection 接口的 .NET 的简单对象映射器或微型 ORM。它提供了一组扩展方法,用于以高性能方式查询和执行针对数据库的命令。与成熟的 ORM 实体框架不同,Dapper 是一个专注于速度的精简选项。Dapper 的实际用法让我们

您好,管理数据访问是构建高效且安全的应用程序的关键组成部分。虽然实体框架 (EF) 是广泛使用的 .NET ORM,但 Dapper 已成为一种流行的轻量级替代方案。

本文将探讨 Dapper 是什么、它的好处和实际用法。我们还将比较 Dapper 和 Entity Framework,并讨论何时选择它们。

什么是Dapper?

Dapper 是用于扩展 IDbConnection 接口的 .NET 的简单对象映射器或微型 ORM。它提供了一组扩展方法,用于以高性能方式查询和执行针对数据库的命令。

与成熟的 ORM 实体框架不同,Dapper 是一个专注于速度的精简选项。

Dapper 的实际用法

让我们通过在 C# 中使用 Dapper 实现用户-订单-产品模型的数据访问层来探索实际用法。创建一个新的 C# 解决方案,用于处理订单、查询订单和按用户搜索订单,我们需要定义必要的类和方法。

Install-Package Dapper

我们正在定义模型类:

  • 用户:包含个人详细信息和订单列表。
  • 订单:包含订单详细信息和产品信息。
  • 产品:包含产品详细信息,如名称、描述和图像链接。
public class User  
{  
    public int Id { get; set; }  
    public string FirstName { get; set; }  
    public string LastName { get; set; }  
    public string MiddleName { get; set; }  
    public string StreetAddress { get; set; }  
    public string City { get; set; }  
    public string State { get; set; }  
    public string Zip { get; set; }  
    public string Mobile { get; set; }  
    public string Email { get; set; }  
    public List\<Order> Orders { get; set; }  
}public class Order  
{  
    public int Id { get; set; }  
    public int UserId { get; set; }  
    public int ProductId { get; set; }  
    public DateTime OrderDate { get; set; }  
    public decimal OrderAmount { get; set; }  
    // Additional order details  
}
public class Product  
{  
    public int Id { get; set; }  
    public string Name { get; set; }  
    public string Description { get; set; }  
    public string Specifications { get; set; }  
    public string ImageLink { get; set; }  
    // Additional product details  
}

初始化 Dapper 和连接字符串

private readonly string _connectionString;  
public OrderDataAccess(string connectionString)  
{  
    _connectionString = connectionString;  
}

创建订单的方法

public void CreateOrder(Order order)  
{  
    using (var connection = new SqlConnection(_connectionString))  
    {  
        var sql = "INSERT INTO Orders (UserId, ProductId, OrderDate, OrderAmount) VALUES (@UserId, @ProductId, @OrderDate, @OrderAmount)";  
        connection.Execute(sql, order);  
    }  
}

按ID查询顺序的方法

public Order GetOrderById(int orderId)  
{  
    using (var connection = new SqlConnection(_connectionString))  
    {  
        return connection.QueryFirstOrDefault<Order>("SELECT * FROM Orders WHERE Id = @Id", new { Id = orderId });  
    }  
}

按用户搜索订单的方法

public IEnumerable<Order> GetOrdersByUserId(int userId)  
{  
    using (var connection = new SqlConnection(_connectionString))  
    {  
        return connection.Query<Order>("SELECT * FROM Orders WHERE UserId = @UserId", new { UserId = userId });  
    }  
}

我们还可以使用一个存储过程来检索特定用户的所有订单以及关联的产品详细信息。此过程将联接 、 和 表,以获取给定用户的综合订单信息。OrdersUsersProducts

CREATE PROCEDURE GetUserOrdersWithDetails  
    @UserId INT  
AS  
BEGIN  
    SELECT o.Id AS OrderId, o.OrderDate, o.OrderAmount,  
           p.Name AS ProductName, p.Description, p.Specifications, p.ImageLink,  
           u.FirstName, u.LastName, u.Email  
    FROM Orders o  
    INNER JOIN Products p ON o.ProductId = p.Id  
    INNER JOIN Users u ON o.UserId = u.Id  
    WHERE o.UserId = @UserId;  
    
ENDpublic class OrderDetail  
{  
    public int OrderId { get; set; }  
    public DateTime OrderDate { get; set; }  
    public decimal OrderAmount { get; set; }  
    public string ProductName { get; set; }  
    public string ProductDescription { get; set; }  
    public string ProductSpecifications { get; set; }  
    public string ProductImageLink { get; set; }  
    public string UserFirstName { get; set; }  
    public string UserLastName { get; set; }  
    public string UserEmail { get; set; }  
}  
  
public IEnumerable\<OrderDetail> GetUserOrdersWithDetails(int userId)  
{  
    using (var connection = new SqlConnection(_connectionString))  
    {  
        return connection.Query<OrderDetail>("GetUserOrdersWithDetails", new { UserId = userId },  
                                             commandType: CommandType.StoredProcedure);  
    }  
}

从订单数据访问中使用这些方法。

var orderDataAccess = new OrderDataAccess(connectionString);  
  
orderDataAccess.CreateOrder(new Order { /* set properties */ });  
  
var order = orderDataAccess.GetOrderById(orderId);  
  
var userOrders = orderDataAccess.GetOrdersByUserId(userId);  
  
var detailedOrders = orderDataAccess.GetUserOrdersWithDetails(userId);

Dapper 与 EF Core 性能指标比较

何时选择 Dapper 或 Entity Framework

选择 Dapper When

  • 性能是重中之重,尤其是对于读取密集型应用程序。
  • 您需要直接控制 SQL 查询。
  • 您正在处理旧数据库或复杂的 SQL 查询。
  • 您更喜欢使用轻量级工具,并且能够轻松地手动处理一些数据库复杂性。

在以下情况下选择实体框架

  • 您需要一个具有更改跟踪和延迟加载等功能的完整 ORM。
  • 您更喜欢使用 LINQ 进行查询。
  • 您正在开发一个以数据为中心的应用程序,其中数据库架构与域模型密切相关。
  • 您希望利用迁移等功能进行数据库架构管理。

Performance & Lightweight是我们获得的主要好处。Dapper

相关留言评论
昵称:
邮箱:
阅读排行