傻傻的勇气 發表於 2016-10-12 00:01:00

.Net开源微型ORM框架测评

<p><span style="font-size: 18pt">&nbsp; 什么是ORM?</span></p>
<p><span style="font-size: 14pt"><img src="https://images2015.cnblogs.com/blog/801909/201610/801909-20161011215534375-311577752.jpg" alt=""></span></p>
<p>&nbsp;</p>
<p>&nbsp; &nbsp; &nbsp; 对象关系映射(英语:Object Relation Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的“虚拟对象数据库”。</p>
<p>&nbsp;</p>
<ul>
<li class="para">一般的ORM包括以下四部分:</li>
<li class="para">一个对持久类对象进行CRUD操作的API;</li>
<li class="para">一个语言或API用来规定与类和类属性相关的查询;</li>
<li class="para">一个规定MAPPING&nbsp;METADATA的工具;</li>
<li class="para">一种技术可以让ORM的实<span style="font-size: 14px">现同事务对</span>象一起进行DIRTYCHECKING<span style="font-size: 14px">, LAZY A</span>SSOCIATION FETCHING以及其他的优化操作。</li>
</ul>
<p><span style="font-size: 18pt">本次对比的.NET ORM框架</span></p>
<p>1. Entity Framework</p>
<p>官网&nbsp;https://msdn.microsoft.com/zh-cn/data/ef.aspx</p>
<p>2. Dapper</p>
<p>官网&nbsp;https://github.com/StackExchange/dapper-dot-net</p>
<p>3. PetaPoco</p>
<p>官网&nbsp;http://www.toptensoftware.com/petapoco/</p>
<p>&nbsp;</p>
<p><span style="font-size: 18pt">对比因素</span></p>
<p><span style="font-size: 18pt"><span style="font-size: 14px">1. 操作的难易程度</span></span></p>
<p><span style="font-size: 18pt"><span style="font-size: 14px">2. 执行的效率</span></span></p>
<p><span style="font-size: 18pt"><span style="font-size: 14px">3. 跨数据库的使用</span></span></p>
<p>&nbsp;</p>
<p><span style="font-size: 18pt">Entity&nbsp;Framework</span></p>
<p>1.新建C#控制台</p>
<p><img src="https://images2015.cnblogs.com/blog/801909/201610/801909-20161011222041968-940361392.jpg" alt="" width="502" height="307"></p>
<p>&nbsp;</p>
<p>2. 使用NuGet引用EF组件</p>
<p>项目引用 右键 管理NuGet程序包 在联机里下载并安装Entity&nbsp;Framework</p>
<p><img src="https://images2015.cnblogs.com/blog/801909/201610/801909-20161011222410609-1201431530.jpg" alt=""></p>
<p>&nbsp;</p>
<p>&nbsp;项目右键 新建 添加 新建项 ADO.NET实体数据模型&nbsp;</p>
<p>我这里的CLN用的是数据库名</p>
<p><img src="https://images2015.cnblogs.com/blog/801909/201610/801909-20161011223104328-1676555266.jpg" alt=""></p>
<p>&nbsp;</p>
<p>&nbsp;添加过以后 有一个实体模型数据向导 选择 从数据库生成 下一步 这里是配置数据库连接 新建连接 将App.Config的实体连接设置为CLNContext</p>
<p><img src="https://images2015.cnblogs.com/blog/801909/201610/801909-20161011223824046-796493147.jpg" alt=""></p>
<p>&nbsp;</p>
<p>然后又出现一个对话框 &nbsp;-- 您要在模型中包含哪些数据库对象,这里把表勾上,点击完成就OK了,然后会弹出两个警告框,这是因为有两个TT模板需要执行,不用管它,确定就行了,这是出现了Edmx数据库模型关系图</p>
<p><img src="https://images2015.cnblogs.com/blog/801909/201610/801909-20161011224623265-602802589.jpg" alt="" width="843" height="422"></p>
<p>&nbsp;</p>
<p>接下来就是进入项目的&nbsp;Program.cs里面写代码了</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span> Main(<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">[] args)
      {
            Stopwatch S </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Stopwatch();//秒表对象 计时
            S.Start();

            </span><span style="color: rgba(0, 0, 255, 1)">var</span> DBContext = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> CLNContext();
            </span><span style="color: rgba(0, 0, 255, 1)">foreach</span> (<span style="color: rgba(0, 0, 255, 1)">var</span> item <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> DBContext.NT_Photo)
            {
                Console.WriteLine(item.PostIP);
            }
         
            Console.WriteLine(S.Elapsed);
            Console.ReadKey();

      }</span></pre>
</div>
<p><img src="https://images2015.cnblogs.com/blog/801909/201610/801909-20161011225743718-1678519974.jpg" alt=""></p>
<p>&nbsp;</p>
<p>NT_Photo 表里有600多条数据,这里看到查询的速度还是蛮快的 &nbsp;EF用时5.9秒</p>
<p>&nbsp;</p>
<p><span style="font-size: 18pt">Dapper</span></p>
<p><span style="font-size: 18pt"><span style="font-size: 14px">1.同样新建控制台程序</span><br></span></p>
<p><span style="font-size: 18pt"><span style="font-size: 14px">2. NuGet引用Dapper</span></span></p>
<p><span style="font-size: 18pt"><span style="font-size: 14px"><img src="https://images2015.cnblogs.com/blog/801909/201610/801909-20161011230647093-1340181217.jpg" alt=""></span></span></p>
<p>Dapper没有EF那么强大,相当于一个SqlHelper,我们需要手动配置连接字符串,这里把刚才EF生成的NT_Photo.cs 模型类,放到项目里面,然后就是就是进入到Program.cs里面写代码了</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Collections.Generic;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Configuration;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Data.SqlClient;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Linq;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Text;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Threading.Tasks;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> Dapper;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Diagnostics;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Threading;

</span><span style="color: rgba(0, 0, 255, 1)">namespace</span><span style="color: rgba(0, 0, 0, 1)"> DapperForsql
{
    </span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> Program
    {
      </span><span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span> Main(<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">[] args)
      {
            
            Stopwatch w </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Stopwatch();
            w.Start();
            </span><span style="color: rgba(0, 0, 255, 1)">var</span> str = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">data source=.;initial catalog=CLN20140830;integrated security=True</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
            SqlConnection Con </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SqlConnection(str);
            </span><span style="color: rgba(0, 0, 255, 1)">var</span> list = Con.Query&lt;NT_Photo&gt;(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">select * from NT_Photo</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);

            </span><span style="color: rgba(0, 0, 255, 1)">foreach</span> (<span style="color: rgba(0, 0, 255, 1)">var</span> item <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> list)
            {
                Console.WriteLine(item.PostIP);
            }
            Console.WriteLine(w.Elapsed);
            Console.ReadKey();
      }
    }
}</span></pre>
</div>
<p>&nbsp;</p>
<p>我们这里用了SqlConnertion对象,因为Dapper是对IDbConnection做了扩展, SqlConnection是实现了IDbConnection,然后在我们引用Dapper的命名空间using Dapper;</p>
<p>&nbsp;</p>
<p><img src="https://images2015.cnblogs.com/blog/801909/201610/801909-20161011231941875-599025328.jpg" alt=""></p>
<p>&nbsp;</p>
<p>这里可以看到,Dapper比EF更快 &nbsp;Dapper用时3.0秒</p>
<p>&nbsp;</p>
<p><span style="font-size: 18pt">PetaPoco</span></p>
<p><span style="font-size: 14px">1.同样新建控制台程序</span></p>
<p><span style="font-size: 14px">2.使用NuGet引用PetaPoco组件</span></p>
<p><span style="font-size: 14px">3.配置App.Config里的连接字符串</span></p>
<div class="cnblogs_code">
<pre>&lt;?xml version=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">1.0</span><span style="color: rgba(128, 0, 0, 1)">"</span> encoding=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">utf-8</span><span style="color: rgba(128, 0, 0, 1)">"</span> ?&gt;
&lt;configuration&gt;
&lt;connectionStrings&gt;
    &lt;add name=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">CLNContext</span><span style="color: rgba(128, 0, 0, 1)">"</span> connectionString=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">data source=.;initial catalog=CLN20140830;integrated security=True;</span><span style="color: rgba(128, 0, 0, 1)">"</span> providerName=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">System.Data.SqlClient</span><span style="color: rgba(128, 0, 0, 1)">"</span> /&gt;
&lt;/connectionStrings&gt;
    &lt;startup&gt;
      &lt;supportedRuntime version=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">v4.0</span><span style="color: rgba(128, 0, 0, 1)">"</span> sku=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">.NETFramework,Version=v4.5</span><span style="color: rgba(128, 0, 0, 1)">"</span> /&gt;
    &lt;/startup&gt;
&lt;/configuration&gt;</pre>
</div>
<p>4. 安装PetaPoco后,同样会自动生成数据库访问上下文和模型Model,这里打开 Models -&gt; Database.tt ,修改&nbsp;ConnectionStringName = "CLNContext";这里要和App.Config里的连接字符串保持一致,更改过以后保存,会自动生成数据库访问上下文,Models -&gt; Database.tt -&gt; Database.cs</p>
<p><img src="https://images2015.cnblogs.com/blog/801909/201610/801909-20161011233059812-1643213548.jpg" alt=""></p>
<p>5.准备工作完毕,就是进入正题了,同样进入到 Program.cs&nbsp;</p>
<div class="cnblogs_code">
<pre>   <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span> Main(<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">[] args)
      {
         
            </span><span style="color: rgba(0, 0, 255, 1)">var</span> Context = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> CLNContext.CLNContextDB();
            Stopwatch s </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Stopwatch();
            s.Start();
            </span><span style="color: rgba(0, 0, 255, 1)">var</span> list = Context.Query&lt;NT_Photo&gt;(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">select * from NT_Photo</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
            </span><span style="color: rgba(0, 0, 255, 1)">foreach</span> (<span style="color: rgba(0, 0, 255, 1)">var</span> item <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> list)
            {
                Console.WriteLine(item.PostIP);
            }
            Console.WriteLine(s.Elapsed);
            Console.ReadKey();


      }</span></pre>
</div>
<p>这里PetaPoco 也有数据库访问上下文CLNContextDB(),不过也是需要写SQL语句的,先看一下查询速度</p>
<p><img src="https://images2015.cnblogs.com/blog/801909/201610/801909-20161011233535031-1841568595.jpg" alt=""></p>
<p>在这里可以看到,PetaPoco貌似更快 PetaPoco用时2.4秒</p>
<p>其实PetaPoco更强大的是,它对模型做了增删改查的方法,这就非常方便了</p>
<div class="cnblogs_code">
<pre> NT_Photo PP = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> NT_Photo();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> res= PP.Insert();<br><br>//res就是返回插入的数据的ID</pre>
</div>
<p><span style="font-size: 18pt">对比结果:</span></p>
<p><span style="font-size: 14px">这里可以看到EF,Dapper,PetaPoco 的差别了</span></p>
<p><span style="font-size: 14px">NT_Photo 600多条数据</span></p>
<p><span style="font-size: 14px">EF &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;------ &nbsp; 5.9秒</span></p>
<p><span style="font-size: 14px">Dapper &nbsp; &nbsp; ------- &nbsp;3.0秒</span></p>
<p><span style="font-size: 14px">PetaPoco &nbsp; ------- &nbsp;2.4秒</span></p>
<p>&nbsp;</p>
<p><span style="font-size: 14px">其实EF第一次的话,会慢一些,第一次会把一些模型数据加载到内存中,后面就非常快了,这里贴一个EF 暖机代码</span></p>
<div class="cnblogs_code">
<pre>      <br>   //EF暖机<br>    <span style="color: rgba(0, 0, 255, 1)">using</span> (<span style="color: rgba(0, 0, 255, 1)">var</span> db = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> CLNContext())
            {
                </span><span style="color: rgba(0, 0, 255, 1)">var</span> objectContext =<span style="color: rgba(0, 0, 0, 1)"> ((IObjectContextAdapter)db).ObjectContext;
                </span><span style="color: rgba(0, 0, 255, 1)">var</span> mappingCollection =<span style="color: rgba(0, 0, 0, 1)"> (System.Data.Entity.Core.Mapping.StorageMappingItemCollection)objectContext.MetadataWorkspace.GetItemCollection(System.Data.Entity.Core.Metadata.Edm.DataSpace.CSSpace);
                mappingCollection.GenerateViews(</span><span style="color: rgba(0, 0, 255, 1)">new</span> System.Collections.Generic.List&lt;System.Data.Entity.Core.Metadata.Edm.EdmSchemaError&gt;<span style="color: rgba(0, 0, 0, 1)">());
            }</span></pre>
</div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="font-size: 14px">总结:每个ORM的存在都有它的价值,不能说哪个哪个好,EF是微软自家推出的,很多代码都是自动生成的,一句SQL语句都不用写,确实非常方便,但是EF的包很大,有5M多,而且微软封装好的也不太利于扩展,像写一些复杂的SQl语句就不是很方便了,Dapper 和PetaPoco相比下来都是比较轻的,而且用起来的话也是非常灵活的。哪一个更适合你的项目,用起来更顺手,才是最好的选择方案。</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>源码源码在这里 </p>
<p>&nbsp;</p>
<p> 黑猫TV http://www.myshowtime.cn </p>
<pre></pre>
<p>&nbsp;</p>
<div class="para">&nbsp;</div>
<div class="para">&nbsp;</div>
<p></audio></p><br><br>
来源:https://www.cnblogs.com/myshowtime/p/5951270.html
頁: [1]
查看完整版本: .Net开源微型ORM框架测评