zoukankan      html  css  js  c++  java
  • ahjesus 捕获entity framework生成的sql语句

    网上这方面的资料很少,找到一个可以用的

    http://code.msdn.microsoft.com/EFProviderWrappers

    里面有dll可以下载,有教程,不过是E文的。

    在Entity Framework中要查看到底最终转译的SQL command是甚麼相当困难,因為EF本身并没有提供像Linq2sql的Log属性来达成此点,这可能是因為Linq2sql比较单纯只对SQL Server,而EF在设计上是与资料库无关.

    目前Entity Framework只能透过ObjectQuery的ToTraceString()来输出转译后的查询SQL语法.但对於SaveChange这类新增修改没有方式能够输出到底实际上的SQL command是甚麼.

    以往要追踪的方式大概就是从SQL Profiler这类资料库附加的软体於资料库端追踪输出,但因為资料库通常不太可能单单只有一隻程式使用,在追踪上有点麻烦.

     

     

    还好有人找出了解决之道并实作Library提供给大家使用.专案参考http://code.msdn.microsoft.com/EFProviderWrappers

    他的做法是从EntityConnection着手,底下图的左边是原来的EF架构,而右边则使此Library的做法,中间多了一层Wrapping Provider.

     

    image_3

     

    再来介绍该如何使用此Library

    1.请先至网站下载档案,因為下载下来為SourceCode所以请先用VS编译过.

    2.编译后寻找EFTracingProvider目录底下的bindebug有两个dll,EFProviderWrapperToolkit.dll与EFTracingProvider.dll.

    3.将这两个dll复製到你想要的目录.

    4.开啟EF专案,使用加入参考方式加入此二个dll.

     

    image

    5.再来就是如何掛载Wrapping Provider,预设情况用EDM tool desinger设计好模型后,在VS中会產生.edmx与.designer.cs档案,而.designer.cs中会產生对应的ObjectContext class, 而ObjectContext class则是使用EDM tool desinger时所输入的名称,预设会是xxxEntities.

    而掛载方式就是继承此class修改其建构式,譬如底下的范例是使用EDM建立一个TestEntities的ObjectContext. 新增一个class档案,命名為ExtendedTestEntities.cs修改如下,

     

        public partial class ExtendedTestEntities : TestEntities
        {
            private TextWriter logOutput;
     
            public ExtendedTestEntities()
                : this("name=TestEntities")
            {
            }
     
            public ExtendedTestEntities(string connectionString)
                : base(EntityConnectionWrapperUtils.CreateEntityConnectionWithWrappers(
                        connectionString,
                        "EFTracingProvider"
                ))
            {
            }
     
            #region Tracing Extensions
     
            private EFTracingConnection TracingConnection
            {
                get { return this.UnwrapConnection<EFTracingConnection>(); }
            }
     
            public event EventHandler<CommandExecutionEventArgs> CommandExecuting
            {
                add { this.TracingConnection.CommandExecuting += value; }
                remove { this.TracingConnection.CommandExecuting -= value; }
            }
     
            public event EventHandler<CommandExecutionEventArgs> CommandFinished
            {
                add { this.TracingConnection.CommandFinished += value; }
                remove { this.TracingConnection.CommandFinished -= value; }
            }
     
            public event EventHandler<CommandExecutionEventArgs> CommandFailed
            {
                add { this.TracingConnection.CommandFailed += value; }
                remove { this.TracingConnection.CommandFailed -= value; }
            }
     
            private void AppendToLog(object sender, CommandExecutionEventArgs e)
            {
                if (this.logOutput != null)
                {
                    this.logOutput.WriteLine(e.ToTraceString().TrimEnd());
                    this.logOutput.WriteLine();
                }
            }
     
            public TextWriter Log
            {
                get { return this.logOutput; }
                set
                {
                    if ((this.logOutput != null) != (value != null))
                    {
                        if (value == null)
                        {
                            CommandExecuting -= AppendToLog;
                        }
                        else
                        {
                            CommandExecuting += AppendToLog;
                        }
                    }
     
                    this.logOutput = value;
                }
            }
     
     
            #endregion
        }

    以上程式码若要套用於你的程式只要修改TestEntities相关描述即可,剩下的可以直接Copy.

    最后在程式中使用方式如下

     

                EFTracingProviderConfiguration.RegisterProvider();
     
                using (ExtendedTestEntities context = new ExtendedTestEntities())
                {                
                    context.CommandExecuting += (sender, e) =>
                    {
                        string s = e.ToTraceString();
                    };
     
                    context.CommandFinished += (sender, e) =>
                    {
                        string s = e.ToTraceString();
                    };
     
                    ...
                }

    透过CommandExecuting与CommandFinished事件则可拦截到最后EF下达SQL命令开始执行与执行后,另外还有执行失败的事件,而透过callback函式的参数之ToTraceString()即可取得完整的转译后之SQL command.

     

    这边要注意一点,第一行的EFTracingProviderConfiguration.RegisterProvider();

    是用来註册这个Library的Provider,因為这个Library除了Tracer SQL外还提供其他的功能,譬如说 Cache机制,都是透过Wrapping Provider来达成,如要了解可以参考官方网站之说明文件.

    而除了在程式中使用,也可透过.net config机制来註册,在相关config中加入如下的描述即可

     

    <system.data>
      <DbProviderFactories>
        <add name="EF Tracing Data Provider"
             invariant="EFTracingProvider"
             description="Tracing Provider Wrapper"
             type="EFTracingProvider.EFTracingProviderFactory, EFTracingProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=def642f226e0e59b" />
        <add name="EF Generic Provider Wrapper"
             invariant="EFProviderWrapper"
             description="Generic Provider Wrapper"
             type="EFProviderWrapperToolkit.EFProviderWrapperFactory, EFProviderWrapperToolkit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=def642f226e0e59b" />
      </DbProviderFactories>
    </system.data>
  • 相关阅读:
    【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验二十一:SDRAM模块④ — 页读写 β
    【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验二十:SDRAM模块③ — 页读写 α
    【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验十九:SDRAM模块② — 多字读写
    【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验十八:SDRAM模块① — 单字读写
    【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验十七:IIC储存模块
    【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验十六:IIC储存模块
    APP安全测试用例梳理
    【python的练习题】:1-100奇数求和(涉及匿名函数filter lambda 的使用)
    反编译 AndroidManifest.xml文件(APP安全测试)
    Android app数据存储的安全测试
  • 原文地址:https://www.cnblogs.com/ahjesus/p/3459158.html
Copyright © 2011-2022 走看看