轻量级ORM框架初探-Dapper与PetaPoco的基本使用

一、EntityFramework

  EF是传统的ORM框架,也是一个比较重量级的ORM框架。这里仍然使用EF的原因在于为了突出轻量级ORM框架的性能,所谓有对比才有更优的选择。

1.1 准备一张数据库表

  (1)For MSSQL

CREATE TABLE [dbo].[Posts]
(
    [Id] INT NOT NULL PRIMARY KEY IDENTITY,
    [CategoryId] INT NOT NULL,
    [Slug] VARCHAR(120) NOT NULL,
    [Title] NVARCHAR(100) NOT NULL,
    [Published] DATETIME NOT NULL,
    [Excerpt] NVARCHAR(MAX) NOT NULL,
    [Content] NVARCHAR(MAX) NOT NULL
);

  (2)For MySQL

CREATE TABLE Posts
(
    Id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    CategoryId INT NOT NULL,
    Slug VARCHAR(120) NOT NULL,
    Title NVARCHAR(100) NOT NULL,
    Published DATETIME NOT NULL,
    Excerpt LONGTEXT NOT NULL,
    Content LONGTEXT NOT NULL
);

1.2 使用Model First方式创建数据模型

  (1)通过nuget添加EF组件引用,然后创建edmx数据模型

  (2)由于EF首次使用存在效率问题,因此采用园子里推荐的EF暖机操作作为测试首次执行的代码

    static void WarmupEntityFramework()
    {
        // EF暖机操作
        using (var db = new MyAppDBContext())
        {
            var objectContext = ((IObjectContextAdapter)db).ObjectContext;
            var mappingCollection = (System.Data.Entity.Core.Mapping.StorageMappingItemCollection)objectContext.MetadataWorkspace.GetItemCollection(System.Data.Entity.Core.Metadata.Edm.DataSpace.CSSpace);
            mappingCollection.GenerateViews(new System.Collections.Generic.List<System.Data.Entity.Core.Metadata.Edm.EdmSchemaError>());
        }
    } 

  (3)写一个读取数据的方法,遍历读取Posts表记录(该表有1万行记录)

    static void ModelFirstReadPosts()
    {
        var dbContext = new MyAppDBContext();
        foreach (var item in dbContext.Posts)
        {
            Console.WriteLine("ID:{0},Title:{1}", item.Id, item.Title);
        }
    } 

  (4)编写入口方法,通过Stopwatch记录测试耗时

    class Program
    {
        static Program()
        {
            WarmupEntityFramework();
        }

        static void Main(string[] args)
        {
            Stopwatch watch = new Stopwatch();
            watch.Start();
            // EF:4.9s
            ModelFirstReadPosts();
            watch.Stop();
            Console.WriteLine("Time consumed : {0} ms", watch.ElapsedMilliseconds);

            Console.ReadKey();
        }

        #region Method01.EntityFramework暖机操作
        static void WarmupEntityFramework()
        {
            // EF暖机操作
            using (var db = new MyAppDBContext())
            {
                var objectContext = ((IObjectContextAdapter)db).ObjectContext;
                var mappingCollection = (System.Data.Entity.Core.Mapping.StorageMappingItemCollection)objectContext.MetadataWorkspace.GetItemCollection(System.Data.Entity.Core.Metadata.Edm.DataSpace.CSSpace);
                mappingCollection.GenerateViews(new System.Collections.Generic.List<System.Data.Entity.Core.Metadata.Edm.EdmSchemaError>());
            }
        }
        #endregion

        #region Method02.Model First方式读取数据库表记录
        static void ModelFirstReadPosts()
        {
            var dbContext = new MyAppDBContext();
            foreach (var item in dbContext.Posts)
            {
                Console.WriteLine("ID:{0},Title:{1}", item.Id, item.Title);
            }
        }
        #endregion
    }

  F5调试运行,首次查询结果如下图所示:

  五次查询之后平均耗时:4.9s

二、Dapper

2.1 关于Dapper

  Dapper是一个开源轻的量级的ORM,只有一个代码文件,完全开源,你可以放在项目里的任何位置,来实现数据到对象的ORM操作,体积小速度快。

2.2 使用Dapper

  (1)通过nuget添加Dapper组件

  (2)针对MSSQL的查询和新增操作

    #region Method01.读取MSSQL单张表
    // 2.7s
    static void DapperReadPosts()
    {
        using (SqlConnection connection = new SqlConnection(connStr))
        {
            var postList = connection.Query<Post>("select * from Posts");
            foreach (var item in postList)
            {
                Console.WriteLine("ID:{0},Title:{1}", item.Id, item.Title);
            }
        }
    }
    #endregion

    #region Method02.读取MSSQL连接查询
    // 2.6s
    static void DapperReadJoin()
    {
        using (SqlConnection connection = new SqlConnection(connStr))
        {
            // 这里查询结果是动态语言类型
            var postList = connection.Query("select Id,Title,GETDATE() as PostDate from Posts");
            foreach (var item in postList)
            {
                Console.WriteLine("ID:{0},PostDate:{1}", item.Id, item.PostDate);
            }
        }
    }
    #endregion

    #region Method03.读取MSSQL多个结果集
    // 2.8s
    static void DapperReadMultiResultSet()
    {
        using (SqlConnection connection = new SqlConnection(connStr))
        {
            using (var reader = connection.QueryMultiple("select * from Posts;select 1000 as Number;"))
            {
                var postList = reader.Read<Post>();
                foreach (var item in postList)
                {
                    Console.WriteLine("ID:{0},Title:{1}", item.Id, item.Title);
                }
            }
        }
    }
    #endregion

    #region Method04.插入MSSQL新记录
    // 0.37s
    static void InsertPostRecord()
    {
        using (SqlConnection connection = new SqlConnection(connStr))
        {
            // 多次插入单条记录
            int count = connection.Execute("insert into Posts values(@CategoryId, @Slug, @Title, @Published, @Excerpt, @Content);", new { CategoryId = 10, Slug = "BOOK", Title = "大话设计模式", Published = DateTime.Now.AddDays(1), Excerpt = "ChengJie", Content = "Design Patterns" });
            Console.WriteLine("受影响行数:{0}", count);

            count = connection.Execute("insert into Posts values(@CategoryId, @Slug, @Title, @Published, @Excerpt, @Content);", new Post() { CategoryId = 10, Slug = "BOOK", Title = "大话数据结构", Published = DateTime.Now.AddDays(1), Excerpt = "ChengJie", Content = "Data Structure" });

            Console.WriteLine("受影响行数:{0}", count);

            // 一次插入多条记录
            IList<Post> postRecords = new List<Post>();
            postRecords.Add(new Post() { CategoryId = 10, Slug = "BOOK", Title = "构建之法-现代软件工程", Published = DateTime.Now.AddDays(1), Excerpt = "ZouXin", Content = "Software Engineering" });
            postRecords.Add(new Post() { CategoryId = 10, Slug = "BOOK", Title = "编程之美", Published = DateTime.Now.AddDays(1), Excerpt = "ZouXin", Content = "I Love Coding" });
            count = connection.Execute("insert into Posts values(@CategoryId, @Slug, @Title, @Published, @Excerpt, @Content);", postRecords);

            Console.WriteLine("受影响行数:{0}", count);
        }
    }
    #endregion

  ① 棒棒哒的地方1:读取多表连接查询

        // 这里查询结果是动态语言类型
        var postList = connection.Query("select Id,Title,GETDATE() as PostDate from Posts");
        foreach (var item in postList)
        {
            Console.WriteLine("ID:{0},PostDate:{1}", item.Id, item.PostDate);
        }

  ② 棒棒哒的地方2:读取多个查询结果集

        using (var reader = connection.QueryMultiple("select * from Posts;select 1000 as Number;"))
        {
            var postList = reader.Read<Post>();
            foreach (var item in postList)
            {
                Console.WriteLine("ID:{0},Title:{1}", item.Id, item.Title);
            }
        }

  ③ 棒棒哒的地方3:一次插入多条数据记录

    // 一次插入多条记录
    IList<Post> postRecords = new List<Post>();
    postRecords.Add(new Post() { CategoryId = 10, Slug = "BOOK", Title = "构建之法-现代软件工程", Published = DateTime.Now.AddDays(1), Excerpt = "ZouXin", Content = "Software Engineering" });
    postRecords.Add(new Post() { CategoryId = 10, Slug = "BOOK", Title = "编程之美", Published = DateTime.Now.AddDays(1), Excerpt = "ZouXin", Content = "I Love Coding" });
    count = connection.Execute("insert into Posts values(@CategoryId, @Slug, @Title, @Published, @Excerpt, @Content);", postRecords);

  ④ 如何跨数据库读取数据记录:依赖于抽象,不依赖于具体

    static void GetPostsCrossMultiDB()
    {
        // 依赖于抽象,不依赖于具体
        using (IDbConnection connection = DbProviderFactories.GetFactory(connSetting.ProviderName).CreateConnection())
        {
            connection.ConnectionString = connSetting.ConnectionString;
            // 使用标准SQL语句屏蔽差异
            var postList = connection.Query<Post>("select * from Posts");
            foreach (var item in postList)
            {
                Console.WriteLine("ID:{0},Title:{1}", item.Id, item.Title);
            }
        }
    } 

  (3)测试结果:

方法 耗时
读取MSSQL单张表 2.7s
读取MSSQL连接查询 2.6s
读取MSSQL多个结果集 2.8s
多次插入MSSQL新记录 148ms

三、PetaPoco

3.1 关于PetaPoco

  PetaPoco是一款适用于.NET应用程序的轻型对象关系映射器。与那些功能完备的ORM(如NHibernate或Entity Framework)不同的是,PetaPoco更注重易用性和性能,而非丰富的功能。使用PetaPoco只需要引入一个C#文件,可以使用强类型的 POCO(Plain Old CLR Object),并支持使用T4模板生成的类等等。

3.2 使用PetaPoco

  (1)通过nuget添加PetaPoco组件

  (2)编辑Database.tt模板文件,前提是首先将连接字符串配置正确

  (3)针对MSSQL的读取和插入操作

    private static void ReadAllPostData()
    {
        using (var context = new MyAppDBContext())
        {
            var postList = context.Query<Post>("select * from Posts");
            foreach (var item in postList)
            {
                Console.WriteLine("ID:{0},Title:{1}", item.Id, item.Title);
            }
        }
    }

    private static void InsertNewPostData()
    {
        var post = new Post
        {
            CategoryId = 1,
            Slug = "BOOK",
            Title = "Microsoft SQL Server 2008技术内幕",
            Content = Guid.NewGuid().ToString(),
            Excerpt = Guid.NewGuid().ToString(),
            Published = DateTime.Now
        };

        var count = post.Insert();

        Console.WriteLine("受影响行数:{0}", count);
    }

  (4)测试结果:

方法 耗时
读取MSSQL单张表 2.7s
插入MSSQL新纪录 30ms

SourceCode

(1)ORMDemo:http://pan.baidu.com/s/1pJAEf0n

Reference

(1)Dapper.NET:https://github.com/StackExchange/dapper-dot-net

作者:周旭龙

出处:http://edisonchou.cnblogs.com

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

时间: 2024-12-28 10:48:56

轻量级ORM框架初探-Dapper与PetaPoco的基本使用的相关文章

轻量级ORM框架:Dapper中的一些复杂操作和inner join应该注意的坑

上一篇博文中我们快速的介绍了dapper的一些基本CURD操作,也是我们manipulate db不可或缺的最小单元,这一篇我们介绍下相对复杂 一点的操作,源码分析暂时就不在这里介绍了. 一:table sql 为了方便,这里我们生成两个表,一个Users,一个Product,sql如下: <1> Users table CREATE TABLE [dbo].[Users]( [UserID] [int] IDENTITY(1,1) NOT NULL, [UserName] [varchar]

.NET轻量级ORM框架Dapper入门精通

一.课程介绍 本次分享课程包含两个部分<.NET轻量级ORM框架Dapper修炼手册>和<.NET轻量级ORM框架Dapper葵花宝典>,阿笨将带领大家一起领略轻量级ORM框架Dapper的魅力. 本次分享课程适合人群范围: 一.<.NET轻量级ORM框架Dapper修炼手册>适合人群如下: 1.我是一个新手,主要工作面向的是MS SQL Server数据库,那么选择修炼手册一定没错. 2.对Dapper从没有过了解或者了解不全面的同学,想通过学习进一步提升对Dappe

分享自己写的基于Dapper的轻量级ORM框架~

1.说明 本项目是一个使用.NET Standard 2.0开发的,基于 Dapper 的轻量级 ORM 框架,包含基本的CRUD以及根据表达式进行一些操作的方法,目前只针对单表,不包含多表连接操作. github:https://github.com/iamoldli/NetSql 2.使用方法 2.2.安装 Install-Package NetSql 2.2.创建实体 创建Article实体类,继承EntityBase public class Article : EntityBase {

c# 轻量级ORM框架 实现(一)

发布一个自己写的一个轻量级ORM框架,本框架设计期初基于三层架构.所以从命名上来看,了解三层的朋友会很好理解. 设计该框架的目的:不想重复的写增删改查,把精力放到功能实现上. 发布改框架的原因:希望给初学者一个参考,希望能给予好的建议,给自己一个展示机会. 在我开始之前,先说明一下,我对"软件工程学"概念东西几乎不通,最高文化程度:初二,所以不喜勿喷. 开始我的orm设计最底层 最底层的是一个DalBase,它是一个抽象的,实现了增删改查的基本操作. 它既然是一个抽象的,那么它的内部就

c# 轻量级 ORM 框架 之 DBHelper 实现 (三)

周末了比较清闲,把自己的orm框架整理了下,开源了. 已经做出来的东西通常感觉有些简单,一些新手或许听到"框架"一类的词觉得有些"高深",简单来说orm就是把ado的封装. 在介绍这个框架的第一篇博文,已经把DalBase介绍了一下设计思路,本篇的DBHelper对象也是给dalBase来用的,可以说框架的所有定义对象都是为了它. 这里起名叫DBHelper,因为我也是从写SQLHelper开始的,DBHelper只不过是所有类型对ado操作的各种方法的封装,所以本

c# 轻量级ORM框架 之 WhereHelper (二)

上篇文章发布了一些设计orm框架基层的和实现,有朋友提出WhereHelper是亮点,能被认可我表示高兴. 我就把WhereHelper设计思想和代码公开下. WhereHelper 的概念就是再拼接where 条件,为了能兼容各种数据库和参数化查询,故封装了该对象. 首先根据我的框架结构: 1.Common库 这里主要定义了,所有层都访问的类型及常用方法,因为是介绍WhereHelper的实现,对其它就不做详细解释了. WhereHelper定义到这一层是想着UI会用到该查询,故把该类型的定义

c# 轻量级 ORM 框架 之 Model解析 (四)

关于orm框架设计,还有必要说的或许就是Model解析了,也是重要的一个环节,在实现上还是相对比较简单的. Model解析,主要用到的技术是反射了,即:把类的属性与表的字段做映射. 把自己的设计及实现思路写出来也希望能有人给很好的优化建议,同时也给新手一点启发吧. 首先先给Model属性定义特性,先普及一下"特性"的概念和为什么用特性(Attribute). 简单来说,特性是给一个类,或方法,或属性 打上一个标记(或者叫附加信息),具体理解还是看例子比较好吧, 在做类与表之间映射时,我

Android轻量级ORM框架ActiveAndroid入门教程(转)

注:没有找到出处,如有侵犯,请告知 开始ActiveAndroid神奇之旅: 在AndroidManifest.xml中我们需要添加这两个 AA_DB_NAME (数据库名称,这个name不能改,但是是可选的,如果不写的话 是默认的"Application.db"这个值) AA_DB_VERSION (数据库版本号,同样是可选的 – 默认为1) <manifest ...> <application android:name="com.activeandro

.NET轻量级ORM框架Dapper修炼手册

一.摘要 1.1.为什么叫本次的分享课叫<修炼手册>? 阿笨希望本次的分享课中涉及覆盖的一些小技巧.小技能给您带来一些帮助.希望您在日后工作中把它作为一本实际技能手册进行储备,以备不时之需,一旦当手头遇到与Dapper修炼手册中相似用法的地方和场景,可以直接拿来进行翻阅并灵活的运用到项目中.最后阿笨建议您可以根据自己在工作中碰到的不同的使用场景,不断的完善此本修炼手册. 废话不多说,直接上干货,我们不生产干货,我们只是干货的搬运工. 四.涉及覆盖的知识点 1.C# Linq To Xml技术.