C#项目实战:Dapper如何让你的数据库操作快如闪电(附完整CRUD示例)

C# 结合 Dapper 开发 Oracle 全能帮助类实战指南 本教程详细介绍了如何使用C#结合Dapper框架开发Oracle11G数据库的全能帮助类。教程涵盖了从环境搭建、核心功能设计到高级功能拓展的全面内容,包括数据库连接配置、基本CRUD操作、批量操作与事务管理、动态SQL构建、分页查询、存储过程调用等。此外,教程还提供了异常处理与日志记录、性能优化策略以及测试与验证的详细指导,帮助开发者构建高效、可维护的数据库操作类。通过学习本教程,开发者能够快速掌握Dapper操作Oracle11G数据库的技巧,提升开发效率,满足企业级应用的需求。 阅读详情

C#项目实战:Dapper如何让你的数据库操作快如闪电(附完整CRUD示例)

最近在几个中小型.NET项目的性能调优中,我反复被一个现象所触动:当数据量增长到一定程度,或是并发请求开始爬升时,原本运行平稳的应用,其响应时间会突然出现令人不安的抖动。深入排查后,数据库访问层往往是那个“木桶的短板”。很多开发者,尤其是从Entity Framework这类全功能ORM入门的,在面对性能瓶颈时,第一反应可能是升级硬件、优化SQL索引,却常常忽略了ORM框架本身带来的开销。这让我想起了几年前的一次重构经历,我们将一个核心服务从Entity Framework迁移到Dapper后,其平均响应时间直接下降了近70%,这不仅仅是数字的变化,更是用户体验质的飞跃。如果你也在为应用的数据库交互效率而困扰,或者正考虑从“重型”ORM转向更轻量、更直接的控制方案,那么深入理解Dapper,或许就是你解开性能枷锁的那把钥匙。本文旨在为.NET开发者,特别是那些关注执行效率和代码简洁性的朋友,提供一个从理论到实践的Dapper深度指南,我们将一起剖析其“快”的本质,并通过一系列可直接落地的CRUD示例,让你亲手感受这种速度的提升。

1. 为何选择Dapper:在性能与便利性之间寻找平衡点

当我们谈论.NET生态中的ORM(对象关系映射)时,Entity Framework无疑是那个最耀眼的明星。它功能强大,提供了一整套从代码优先(Code-First)到数据库优先(Database-First)的完整解决方案,极大地提升了开发效率,尤其适合业务逻辑复杂、需要快速迭代的项目。然而,这份强大与便利背后,隐藏着性能上的妥协。EF通过其变更追踪(Change Tracking)、LINQ to SQL的翻译层以及复杂的映射机制,在运行时生成了大量的间接调用和动态SQL,这些开销在数据量小、并发低时微不足道,但在高负载场景下,就可能成为性能瓶颈。

Dapper的出现,正是为了填补“原生ADO.NET的繁琐”与“全功能ORM的臃肿”之间的空白。它由Stack Overflow团队开发并用于其生产环境,其设计哲学极其明确:极致的性能与透明的控制。Dapper本质上是一个“微ORM”或“扩展方法集”,它不尝试管理对象状态、不生成迁移脚本、也不提供LINQ查询。它所做的,只是将SQL查询结果高效地映射到你定义的POCO(Plain Old CLR Object)对象上。

那么,Dapper的“快”究竟从何而来?我们可以从几个核心机制来理解:

  • 基于Emit的动态方法生成:这是Dapper性能的基石。当第一次执行某个查询到特定类型的映射时,Dapper会使用.NET的System.Reflection.Emit命名空间,在内存中动态生成一个高度优化的、针对该类型和查询结果的映射方法(IL代码)。这个过程虽然第一次执行时有轻微开销,但生成的方法会被缓存起来。后续所有相同类型的映射操作,都将直接调用这个编译好的方法,其速度几乎等同于手写硬编码的赋值语句,远快于每次查询都使用反射。
  • 无状态与轻量级:Dapper自身不维护任何与数据库连接或实体对象相关的状态。它仅仅是一组扩展了IDbConnection接口的静态方法。这意味着几乎没有内存开销,也没有上下文(DbContext)管理的负担。
  • SQL透明:你写的就是最终执行的SQL。这带来了两个好处:第一,避免了LINQ提供器翻译可能带来的低效或意外的SQL;第二,开发者可以充分利用特定数据库的高级特性,并精确地优化每一条查询语句。

为了更直观地对比,我们来看一个简单的性能定位表格,这并非严谨的基准测试,但反映了在典型场景下的趋势差异:

特性维度DapperEntity Framework Core (非跟踪查询)原生 ADO.NET (DataReader)
映射速度极快 (动态编译缓存)快 (但仍有表达式树解析开销)最快 (手动映射,无额外层)
内存开销极低中等 (上下文、变更追踪器)最低
开发效率高 (需手写SQL)极高 (LINQ, 迁移)低 (全手动)
学习曲线平缓陡峭陡峭
适用场景高性能API、报表、批处理、已有复杂SQL快速业务应用开发、原型验证极致性能追求、完全控制

注意:上表对比旨在提供直观认知。Entity Framework Core在近年版本中性能已有大幅提升,其“非跟踪查询”(AsNoTracking)模式性能接近Dapper。选择的关键在于项目需求:需要绝对的控制权和可预测的性能,选Dapper;追求极致的开发速度和丰富的内置功能,EF Core是优秀选择。

因此,如果你的项目属于数据驱动型,拥有大量读写操作、复杂的查询逻辑,或者你对性能有严苛的要求,Dapper就是一个极具吸引力的选项。它让你在享受对象映射便利的同时,保留了手写SQL的精准与高效。

2. 从零开始:项目集成与基础配置实战

理论说得再多,不如动手一试。让我们从一个干净的.NET 6/8控制台或Web API项目开始,一步步将Dapper集成进来,并完成基础的数据库连接与查询。

首先,通过NuGet包管理器安装Dapper。在Visual Studio中,你可以通过包管理器控制台执行:

Install-Package Dapper

或者使用.NET CLI:

dotnet add package Dapper

Dapper对数据库提供程序本身没有依赖,它只依赖于System.Data.Common。因此,你还需要安装对应数据库的ADO.NET驱动,例如对于SQL Server:

dotnet add package System.Data.SqlClient
# 或使用更新的 Microsoft.Data.SqlClient
dotnet add package Microsoft.Data.SqlClient

安装完成后,我们来建立一个简单的数据模型和数据库上下文。假设我们有一个Product(产品)表。

// 产品实体类
public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public int Stock { get; set; }
    public DateTime CreatedAt { get; set; }
}

// 一个简单的数据库连接帮助类(实际项目建议使用依赖注入)
public static class ConnectionFactory
{
    private static readonly string _connectionString = "Your_SQL_Server_Connection_String";

    public static SqlConnection CreateConnection()
    {
        return new SqlConnection(_connectionString);
    }
}

接下来,我们实现第一个查询:获取单个产品。注意Dapper扩展方法QueryFirstOrDefaultAsync的使用。

public class ProductRepository
{
    public async Task<Product> GetProductByIdAsync(int id)
    {
        // 使用using语句确保连接被正确释放
        using var connection = ConnectionFactory.CreateConnection();
        // 定义参数化SQL查询,防止SQL注入
        string sql = "SELECT Id, Name, Price, Stock, CreatedAt FROM Products WHERE Id = @ProductId";
        // 执行查询并映射。@ProductId参数通过匿名对象传递。
        var product = await connection.QueryFirstOrDefaultAsync<Product>(sql, new { ProductId = id });
        return product;
    }
}

这段代码清晰地展示了Dapper的工作流程:打开连接、执行参数化SQL、将结果映射到Product对象、关闭连接。映射之所以能成功,是因为我们实体类的属性名Id, Name等与数据库表的列名完全一致。这就是Dapper默认的自动映射。

但现实世界的数据库设计往往与我们的领域模型不完全匹配。例如,数据库列名可能是product_id、product_name,而我们的C#属性使用Pascal命名法Id、Name。Dapper提供了灵活的方案来处理这种不一致:

  1. SQL别名映射:在查询中直接使用AS关键字,这是最直接和推荐的方式,因为它将映射关系清晰地表达在SQL中。
    string sql = "SELECT product_id AS Id, product_name AS Name, price AS Price FROM products WHERE product_id = @Id";
    
  2. 自定义属性映射:Dapper支持通过[Column]属性(需要Dapper.Contrib扩展)或实现自定义类型映射器(SqlMapper.ITypeMap),但这通常用于更复杂的场景或遗留系统集成。对于新项目,SQL别名更加简洁明了。

3. 核心CRUD操作详解与性能陷阱规避

掌握了基础查询后,我们来构建一套完整的增删改查(CRUD)操作。这里的关键不仅是写出能运行的代码,更要写出高效、安全的代码。

3.1 插入(Create)操作与批量插入优化

单条插入操作非常直观。Dapper的ExecuteAsync方法用于执行不返回结果集的命令。

public async Task<int> CreateProductAsync(Product product)
{
    using var connection = ConnectionFactory.CreateConnection();
    string sql = @"
        INSERT INTO Products (Name, Price, Stock, CreatedAt)
        VALUES (@Name, @Price, @Stock, @CreatedAt);
        SELECT CAST(SCOPE_IDENTITY() AS INT);"; // 获取自增ID

    // 执行查询,并返回单个值(新插入的Id)
    var newId = await connection.ExecuteScalarAsync<int>(sql, product);
    return newId;
}

这里我们使用了ExecuteScalarAsync来获取插入后生成的自增主键ID。注意SQL语句中参数@Name、@Price等,它们与product对象的属性名自动匹配。

然而,在需要插入大量数据的场景(如数据导入),逐条插入将是灾难性的。Dapper原生支持通过传递一个IEnumerable<T>参数来执行批量操作,但需要注意的是,对于INSERT,Dapper默认会将其展开为一条带有多个值列表的SQL语句(如INSERT INTO ... VALUES (...), (...), ...)。这种方式虽然比循环单条插入快很多,但当列表非常大时(例如超过1000行),可能会遇到SQL语句长度限制或性能下降。

更高效的批量插入策略是使用表值参数(Table-Valued Parameters, TVP) 或专门的批量操作库(如SqlBulkCopy)。下面是一个使用Dapper执行基于TVP的批量插入示例:

首先,在数据库中定义一个表类型:

CREATE TYPE dbo.ProductTableType AS TABLE
(
    Name NVARCHAR(100),
    Price DECIMAL(18, 2),
    Stock INT
);

然后在C#代码中:

public async Task BulkInsertProductsAsync(IEnumerable<Product> products)
{
    using var connection = ConnectionFactory.CreateConnection();
    await connection.OpenAsync();

    // 创建一个DataTable,其结构匹配自定义表类型
    var table = new DataTable();
    table.Columns.Add("Name", typeof(string));
    table.Columns.Add("Price", typeof(decimal));
    table.Columns.Add("Stock", typeof(int));

    foreach (var p in products)
    {
        table.Rows.Add(p.Name, p.Price, p.Stock);
    }

    // 使用Dapper执行存储过程或动态SQL,传递DataTable作为参数
    var parameters = new { ProductList = table.AsTableValuedParameter("dbo.ProductTableType") };
    await connection.ExecuteAsync("usp_InsertProducts", parameters, commandType: CommandType.StoredProcedure);
}

提示:对于超大规模(数十万以上)的批量插入,SqlBulkCopy类仍然是.NET中性能最高的选择,你可以将其与Dapper混合使用,Dapper负责查询,SqlBulkCopy负责大数据量写入。

3.2 查询(Read)操作进阶:多表关联与结果映射

Dapper在处理复杂查询时同样游刃有余。它支持将查询结果映射到多个关联对象上。假设我们还有一个Category表,产品属于某个类别。

public class Category
{
    public int Id { get; set; }
    public string Name { get; set; }
}
// 扩展Product类
public class ProductDetail : Product
{
    public Category Category { get; set; }
}

public async Task<IEnumerable<ProductDetail>> GetProductsWithCategoryAsync()
{
    using var connection = ConnectionFactory.CreateConnection();
    string sql = @"
        SELECT p.*, c.Id AS CategoryId, c.Name AS CategoryName
        FROM Products p
        INNER JOIN Categories c ON p.CategoryId = c.Id";

    // 使用QueryMultiMap进行复杂映射
    var productDict = new Dictionary<int, ProductDetail>();

    var list = await connection.QueryAsync<ProductDetail, Category, ProductDetail>(
        sql,
        (product, category) =>
        {
            // 检查字典中是否已有该产品(基于Id)
            if (!productDict.TryGetValue(product.Id, out var productEntry))
            {
                productEntry = product;
                productEntry.Category = category;
                productDict.Add(productEntry.Id, productEntry);
            }
            // 如果是一对多关系,这里可以处理集合添加
            return productEntry;
        },
        splitOn: "CategoryId" // 告诉Dapper从`CategoryId`列开始分割数据映射到第二个对象(Category)
    );

    return productDict.Values;
}

QueryAsync的重载方法允许我们一次性读取数据行,并将其分割映射到多个对象上。splitOn参数至关重要,它指示Dapper从哪个列开始属于第二个对象。对于更复杂的一对多关系(如一个产品有多个评论),可以使用QueryMultiple方法执行返回多个结果集的查询,然后分别用Read<T>()方法读取。

3.3 更新(Update)与删除(Delete)操作

更新和删除操作相对简单,重点是使用参数化查询以确保安全。

// 更新操作
public async Task<bool> UpdateProductPriceAsync(int productId, decimal newPrice)
{
    using var connection = ConnectionFactory.CreateConnection();
    string sql = "UPDATE Products SET Price = @Price, UpdatedAt = GETUTCDATE() WHERE Id = @Id";
    // ExecuteAsync返回受影响的行数
    int rowsAffected = await connection.ExecuteAsync(sql, new { Id = productId, Price = newPrice });
    return rowsAffected > 0;
}

// 删除操作(软删除示例)
public async Task<bool> SoftDeleteProductAsync(int productId)
{
    using var connection = ConnectionFactory.CreateConnection();
    string sql = "UPDATE Products SET IsDeleted = 1, DeletedAt = GETUTCDATE() WHERE Id = @Id";
    int rowsAffected = await connection.ExecuteAsync(sql, new { Id = productId });
    return rowsAffected > 0;
}

3.4 事务处理:保证数据一致性

在涉及多个数据库操作(如订单创建同时扣减库存)时,事务是保证数据一致性的关键。Dapper完美支持标准ADO.NET事务。

public async Task<bool> PlaceOrderAsync(Order newOrder, List<OrderItem> items)
{
    using var connection = ConnectionFactory.CreateConnection();
    await connection.OpenAsync(); // 事务需要显式打开连接

    // 开始事务
    using var transaction = await connection.BeginTransactionAsync();

    try
    {
        // 1. 插入订单主记录
        string orderSql = @"INSERT INTO Orders (CustomerId, TotalAmount, Status) 
                            VALUES (@CustomerId, @TotalAmount, @Status);
                            SELECT CAST(SCOPE_IDENTITY() AS INT);";
        int orderId = await connection.ExecuteScalarAsync<int>(orderSql, newOrder, transaction);
        
        // 2. 插入订单明细
        foreach (var item in items)
        {
            item.OrderId = orderId;
            string itemSql = @"INSERT INTO OrderItems (OrderId, ProductId, Quantity, UnitPrice) 
                               VALUES (@OrderId, @ProductId, @Quantity, @UnitPrice)";
            await connection.ExecuteAsync(itemSql, item, transaction);
            
            // 3. 扣减产品库存(在同一个事务中)
            string updateStockSql = @"UPDATE Products SET Stock = Stock - @Quantity 
                                      WHERE Id = @ProductId AND Stock >= @Quantity";
            int updated = await connection.ExecuteAsync(updateStockSql, 
                new { ProductId = item.ProductId, Quantity = item.Quantity }, transaction);
            if (updated == 0)
            {
                throw new InvalidOperationException($"产品 {item.ProductId} 库存不足。");
            }
        }

        // 所有操作成功,提交事务
        await transaction.CommitAsync();
        return true;
    }
    catch (Exception ex)
    {
        // 任何失败,回滚事务
        await transaction.RollbackAsync();
        // 记录日志或重新抛出异常
        throw;
    }
}

这个例子展示了在一个事务内串联多个Dapper操作。关键点在于将transaction对象传递给每一个ExecuteAsync或QueryAsync调用。这样,所有这些操作都成为了同一个事务的一部分,要么全部成功,要么全部回滚。

4. 超越基础:高级特性与生产环境最佳实践

当你熟练掌握了Dapper的基本CRUD后,以下这些高级特性和实践建议,能帮助你在生产环境中构建更健壮、更易维护的数据访问层。

动态条件查询构建:我们经常需要根据前端传入的过滤条件动态构建WHERE子句。直接拼接字符串容易导致SQL注入漏洞。一个安全的做法是使用DynamicParameters和StringBuilder。

public async Task<IEnumerable<Product>> QueryProductsAsync(string nameFilter, decimal? minPrice, decimal? maxPrice)
{
    using var connection = ConnectionFactory.CreateConnection();
    
    var sqlBuilder = new StringBuilder("SELECT * FROM Products WHERE 1=1");
    var parameters = new DynamicParameters();
    
    if (!string.IsNullOrWhiteSpace(nameFilter))
    {
        sqlBuilder.Append(" AND Name LIKE @Name");
        parameters.Add("Name", $"%{nameFilter}%");
    }
    if (minPrice.HasValue)
    {
        sqlBuilder.Append(" AND Price >= @MinPrice");
        parameters.Add("MinPrice", minPrice.Value);
    }
    if (maxPrice.HasValue)
    {
        sqlBuilder.Append(" AND Price <= @MaxPrice");
        parameters.Add("MaxPrice", maxPrice.Value);
    }
    sqlBuilder.Append(" ORDER BY CreatedAt DESC");
    
    return await connection.QueryAsync<Product>(sqlBuilder.ToString(), parameters);
}

DynamicParameters提供了类型安全的参数添加方式,并且能正确处理null值。

性能监控与调优:虽然Dapper很快,但不合理的用法仍会导致问题。

  • 连接管理:始终使用using语句或在依赖注入框架中管理连接的生命周期(如Scoped生命周期),避免连接泄露。
  • 查询性能:Dapper执行的是你写的SQL,因此SQL本身的效率至关重要。学会使用SQL Server Profiler、EF Core的日志或像MiniProfiler这样的工具来监控生成的SQL和执行时间。特别注意N+1查询问题——在循环中执行查询。应使用IN语句或上文提到的多映射、QueryMultiple来一次性获取数据。
  • 异步流式处理:对于返回大量数据的查询,可以使用QueryUnbufferedAsync(如果数据库驱动支持)或DbDataReader进行流式处理,避免一次性将所有数据加载到内存。

与依赖注入(DI)框架集成:在现代.NET应用中,推荐使用依赖注入来管理数据库连接和仓储实例。

// 在Startup.cs或Program.cs中注册服务
services.AddScoped<IDbConnection>(sp => 
    new SqlConnection(Configuration.GetConnectionString("DefaultConnection")));
services.AddScoped<IProductRepository, ProductRepository>();

// 仓储类构造函数注入
public class ProductRepository : IProductRepository
{
    private readonly IDbConnection _dbConnection;
    
    public ProductRepository(IDbConnection dbConnection)
    {
        _dbConnection = dbConnection;
    }
    
    public async Task<Product> GetByIdAsync(int id)
    {
        // 注意:当连接由DI容器管理时,通常不在方法内打开/关闭,
        // 而是在请求开始和结束时由容器或中间件管理。对于Dapper,
        // 如果连接未打开,它在执行命令时会自动打开和关闭。
        return await _dbConnection.QueryFirstOrDefaultAsync<Product>(...);
    }
}

最后,记住没有银弹。Dapper在追求极致性能和透明控制的同时,也意味着你需要承担更多责任:手写和维护SQL、手动处理对象关系映射、缺乏迁移工具等。在项目启动时,根据团队技能、项目规模和性能要求,在Dapper和Entity Framework Core之间做出明智的权衡,有时甚至在同一个项目中混合使用它们(在性能关键模块用Dapper,在复杂业务域用EF Core),也是一种非常实用的架构策略。在我最近参与的一个微服务项目中,核心交易服务使用了Dapper来处理高并发的订单读写,而后台的管理系统则使用了EF Core来快速实现复杂的业务配置功能,两者通过清晰的接口隔离,相得益彰。

掌握 C# 数据库操作:ADO.NET、EF Core 与 Dapper 的最佳实践 在 C# 中,ADO.NET、Entity Framework Core 和 Dapper 各有优缺点。根据你的项目需求,选择合适的数据库操作方式可以有效提高开发效率与性能。掌握这些技术,并在实际项目中灵活运用,能够帮助你高效地进行数据库开发和优化。 阅读详情

相关推荐

Dapper ORM 框架跟我学:第十四课 - Dapper 第三方库 Dapper-Contrib 的使用

Dapper-Contrib 是 Dapper 的一个扩展库,它为 Dapper 提供了额外的功能,使得我们可以更方便地进行 CRUD(创建、读取、更新、删除)操作。通过使用 Dapper-Contrib,我们可以减少手动编写 SQL 查询的工作量,提高开发效率。在这节课中,我们学习了如何使用 Dapper-Contrib 来简化数据库操作。通过合理使用 Dapper-Contrib 提供的数据标注和扩展方法,我们可以大大减少手动编写 SQL 查询的工作量,提高开发效率。数据标注:通过使用[Key]

caifox的博客 1935

分享一个 C# 使用 Dapper 的实战详细例子

在这篇文章中,我们将一起探讨如何使用 Dapper 进行高效的数据库操作。作为一个轻量级的 ORM 工具,Dapper 以其简洁性和强大性能而受到众多程序员的青睐。我们通过一个详细完整的例子,从安装 Dapper、配置数据库连接、创建实体类、执行数据库操作等,让您轻松掌握这个实用工具的魅力

yangshuquan的专栏 1395

C#数据访问革命:Dapper连接SQL Server的3种方式,为何比EF快10倍?

Dapper高效连接SQL Server实战指南 本文深入对比Dapper与EF Core在SQL Server数据访问中的差异,通过性能测试和实战案例揭示Dapper的10倍性能优势。核心内容: 性能对比 Dapper查询速度达EF的10倍(1.2ms vs 12.3ms) 批量插入效率提升10倍(85ms vs 850ms) 三大连接方式 基础查询:强类型映射与参数化防注入 存储过程:支持输入/输出参数 动态SQL:多表JOIN与条件拼接 高并发实战 电商系统实现<1ms响应 金融系统支持10,0

java专栏 1186

C#项目实战:Dapper如何帮你5分钟搞定数据库CRUD操作?

本文通过一个C#项目实战案例,详细演示了如何使用轻量级ORM框架Dapper在5分钟内快速搭建数据库CRUD操作骨架。文章从环境准备、实体定义到核心增删改查代码实现,逐步指导开发者掌握Dapper的高效数据映射与SQL控制能力,并涵盖事务处理、性能优化及项目集成等进阶实践,帮助中小型项目团队提升开发效率。

q6r7s8t9的博客 956

Dapper.SimpleCRUD:让数据库操作快到飞起!C#开发者必学的CRUD黑科技

摘要: Dapper.SimpleCRUD 是 Dapper 的轻量级扩展库,简化数据库 CRUD 操作,提供高性能、零配置的解决方案。核心功能包括属性映射([Table]、[Key])、异步支持、动态查询和分页优化。通过简单 API(如 Insert()、Get())实现快速开发,支持主键自动返回和复杂条件筛选。适用于高并发场景,显著提升开发效率,减少冗余 SQL 编写。

墨夶的博客 1587

C# 5分钟学会 vs. 传统方式:Dapper.SimpleCRUD如何让CRUD操作变得如此简单?

接下来就是创建与数据库表相对应的数据模型类了。这里需要注意的是,为了让Dapper.SimpleCRUD能够正确识别这些类,并将其映射回相应的表结构,我们需要给类和属性添加特定的注解。set;set;set;// 额外的、不在数据库中的属性[EditablefalseFirstNameget;set;get;set;get;set;get;set;

java专栏 832

C#搭配Dapper玩转SQLite3:从零开始的数据库操作实战(附避坑指南)

本文详细介绍了C#如何搭配Dapper轻量级ORM操作SQLite3数据库,提供从环境搭建、驱动选择到CRUD实战的完整指南。内容涵盖连接管理、事务处理、异步操作及性能优化等核心技巧,并重点分享了文件锁定、类型映射等常见“避坑”经验,帮助开发者构建高效简洁的数据访问层。

cc789的博客 982

C# 中 Dapper 轻量级 ORM 的应用详解

接下来,我们将通过具体的示例来展示如何在 C# 中使用 Dapper 进行数据库操作。跟着我一起,一步步来,你会发现这一切并不难。📋。

java专栏 958

c#中使用dapper_如何在C#中使用Dapper ORM

c#中使用dapper 对象关系映射器(ORM)已经使用了很长时间,以消除编程语言的对象模型与关系数据库中的数据模型之间存在的阻抗失配。 Dapper是由Stack Overflow团队开发的开源轻量级ORM。 与其他ORM相比,Dapper的速度非常快,主要是因为它的重量轻。 Dapper的设计注重性能和易用性。 它为使用事务,存储过程或批量插入数据的静态和动态对象绑定提供支持。 [...

cxu0262的博客 829

C#与Dapper的完美结合:打造轻量级数据库访问的新标杆

Dapper是由Stack Overflow团队开发并维护的一个开源微ORM库,最初是为了解决他们在处理大量数据库查询时遇到的问题。它通过扩展接口,提供了一系列便捷的方法来执行SQL语句,并将结果映射为强类型的对象集合。轻量级:核心代码量小,依赖少,不会给项目带来过多负担。高性能:直接操作ADO.NET底层API,避免了不必要的抽象层次,确保了最佳的执行效率。灵活性高:支持任意复杂的SQL查询,包括存储过程调用、批量插入等高级特性。学习成本低:语法直观易懂,文档详尽,即使是新手也能快速上手。

墨夶的博客 1614

C# 数据访问利器:Dapper 连接 SQL Server 的7大步骤详解

通过今天的分享,相信大家已经学会了如何使用 Dapper 轻松连接 SQL Server 并执行 CRUD 操作。Dapper 的简洁和高效使得数据访问变得更加简单,非常适合中小型项目的开发。如果你有任何问题或建议,欢迎在评论区留言交流。希望这篇文章能帮助你在 C# 开发的道路上更进一步!🎉✨。

java专栏 1101

一个C#扩展库,让Dapper的CRUD操作更简单

Dommel是Dapper的简单扩展,基于POCO实现基本的CRUD,提供手动和自动多重映射、查询列表、同步异步方法,同时支持LINQ等功能。02。

成长的足迹 763

航测倾斜摄影如何用Smart3D(ContextCapture)处理大疆无人机照片生成三维模型

本篇内容主要介绍Smart3D(ContextCapture)处理大疆无人机数据操作步骤 详细步骤如下 1.拷贝大疆无人机航拍的完整照片 2.打开Smart3D(ContextCapture)软件新建一个工程 3.影像选择项下选择添加影像 4.检查影像是否可以正常打开 5.提交空三计算,名称默认即可(不能带文字或字符) 6.没有控制点就默认选择 7.第一次空三默认设置 8.完成设置提交空三计算 9.打开引擎端开始计算 10.空三计算完成 11.查看空三质量报告是否有问题 12.空三没有

Miss程晨 1万+

C#进阶-Dapper原理解析与使用教程

本文详细介绍了Dapper在C#中的使用方法,包括Dapper的基本概念、与其他持久层框架的比较、基本语法和高级语法的使用,并通过实例讲解了如何在项目中集成和使用Dapper。最后,总结了Dapper的优缺点及其在实际开发中的应用场景。一、Dapper介绍1. Dapper介绍Dapper是一个轻量级的ORM(对象关系映射...

cnzzs的博客 2507

基于 Python 的 LIF 模型:探索神经元同步与小世界网络

首先,我们定义了一个LIFNeuronself.soma.L = self.soma.diam = 12.6157 # 固定神经元形状self.cm = cm # 电容self.V_rest = V_rest # 静息电位self.V = V_rest # 初始化膜电位在初始化过程中,每个神经元被赋予初始的静息电位,并且其膜电位会在后续的模拟过程中动态变化。

qq_36224726的博客 1428

手把手教你用DaVinci Configurator配置AUTOSAR SWC接口(含RTE避坑指南)

本文提供了一份基于DaVinci Configurator工具的AUTOSAR软件组件(SWC)接口配置实战指南。文章详细拆解了SR(发送者-接收者)和CS(客户端-服务器)接口的配置流程,并重点分享了运行时环境(RTE)生成阶段在多核部署、数据类型匹配等常见陷阱中的避坑方案与调试技巧,旨在帮助汽车电子工程师高效完成配置并规避错误。

uuu88的博客 550

Dapper ORM 框架跟我学:第十五课 - Dapper 第三方库 Dapper.SimpleCRUD 的使用

Dapper.SimpleCRUD 是 Dapper 的一个轻量级扩展库,它提供了简单的 CRUD 操作功能,使得我们可以更方便地进行数据库操作。通过使用 Dapper.SimpleCRUD,我们可以减少手动编写 SQL 查询的工作量,提高开发效率。在这节课中,我们学习了如何使用 Dapper.SimpleCRUD 来简化数据库操作。

caifox的博客 1088

BMW Standard Tools 宝马FSC工具套装下载

这是一款非常专业的一套宝马编码工具,懂行的人自然知道他的用处,不懂行的人,我解释再多也不会明白的,需要的拿去吧。软件名:BMW Standard Tools包含工具:BMW Coding Tool v2.50、change Language、CIC Mafia、Dr.Gini B021、EasyConnect、EDIABAS Konfigurator v1.1、EDIABAS Konfigurator v2.0.0、FSC-Tools_2.18、FSTool_v2_CarServer、INPA、ITool

Zj_arrow的博客 7009

Dapper ORM 框架跟我学:第一课 - Dapper ORM 介绍

Dapper 是一个轻量级的微 ORM(微型对象关系映射器),由 Stack Overflow 团队开发并开源。它的设计目标是提供一种简单、高效的方式来与数据库交互,同时保持代码的简洁性和性能。与传统的 ORM 框架不同,Dapper 不会生成复杂的 SQL 查询,也不会管理实体之间的复杂关系。相反,它专注于将 SQL 查询的结果直接映射到 C# 对象,帮助你快速执行数据库操作,而不需要编写大量的样板代码。

caifox的博客 1616

『ISOBUS 入门』第 00 节 导言:ISOBUS 的宏观图景与入门路径

ISOBUS 是由三部分构成的集成系统:两段CAN网络(拖拉机与农具侧)、标准化通信约定及认证流程。其核心在于通过统一协议实现跨品牌设备即插即用。标准体系以ISO 11783为基础,分层涵盖物理层、传输层至应用层,关键功能如虚拟终端(VT)、任务控制器(TC)和文件服务器依赖严格的会话管理与角色分工。实际部署中,总线上传输多种协议报文,故障排查需结合地址声明、多包传输与角色权限分析。学习应从真实报文入手,建立“角色—数据流—功能块”认知链,避免仅学标准或仿真替代实测,方能有效应对复杂现场问题。

linx295的博客 286

芯片测试:WAT、CP、FT

最近部门来了一个日本回来的同事,虽然他尽量用非常Poor的中文给我解释一些东西,其中还夹杂着一些英文让我很受挫,于是最近来学一下WAT中的常用的单词含义。直接去查缩写、查单词很难去记住,要把具体的东西放在具体的场景,引发知识的连接才会在脑子里留下一定的映像。感兴趣的一起来学习一下这篇不错的文章吧。注释是我查询记录,如有不妥,欢迎指出修正。

叫好与叫座虽然不是对立面,但想在同一个作品中达到双重效果很难。 5092

C#进阶-轻量级ORM框架Dapper的使用教程与原理详解

本文详细介绍了Dapper在C#中的使用方法,包括Dapper的基本概念、与其他持久层框架的比较、基本语法和高级语法的使用,并通过实例讲解了如何在项目中集成和使用Dapper。Dapper以其高效的性能和简洁的API受到开发者的青睐,适用于各种数据库操作需求。本文还将深入探讨Dapper的核心原理,通过内部代码展示其工作机制。最后,总结了Dapper的优缺点及其在实际开发中的应用场景,为开发者提供全面的指导。

踏雨歌青春,诗酒趁年华 1万+

海康网口相机不能被flexscan3d识别到MVS版本为4.6.1,flex为3.3.24在MVS中能够检测到,但是在flex中只能看到电脑自带相机,如何解决?

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。

**My Coding Family** 1049

C#与Dapper框架实战:从零基础到高效数据库操作

本文为C#开发者提供了Dapper框架的实战指南。Dapper作为一款轻量级ORM,在C#项目中能显著提升数据库操作性能与开发效率。文章从零基础快速上手讲起,详细解析了增删改查、事务处理等核心操作,并分享了参数化查询、异步编程、性能优化等进阶技巧与最佳实践,帮助开发者规避常见陷阱,实现高效、安全的数据访问。

weixin_29212429的博客 226

终于搞定!Cloudflare Tunnel 报错 Error 1033,一次完整修复记录

最近遇到了 Cloudflare Tunnel Error 1033 报错的问题,本文记录了完整的排查和解决方案💡

XiaoqiangClub的博客 1786

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

C# ASP.NET ORM 框架实战:Dapper 与 NHibernate 从入门到避坑

本文对比了两种主流ORM框架Dapper和NHibernate的特点与应用场景。Dapper作为轻量级ORM,以高性能和灵活性著称,适合需要精细控制SQL的场景,通过代码示例展示了其CRUD操作及常见问题(如SQL注入、类型匹配、连接释放)。NHibernate则是功能全面的老牌框架,适合企业级应用,提供缓存、延迟加载等高级特性,但配置较为复杂。文章通过生活类比帮助理解框架差异,并总结了实际开发中的避坑指南,为开发者选择合适ORM提供了实用参考。

William_cl的博客 799

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

上一篇: Android车载系统Launcher开发避坑指南:从权限申请到Activity嵌入(附CarLauncher源码分析)
下一篇: 从Embedding到RoPE:图解Transformer位置编码的进化之路
Python
博客等级 码龄26年 1973粉丝 1567原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值