EF团队推出了一套比较完整的缓存和SQL执行日志的解决方案,EFProviderWrappers。他们的做法是在原来的EF Provider之上,再加一层包装,通过这层包装拦截,进行数据缓存和日志监控。数据缓存功能与NHibernate的二级缓存相比,优势在于简单轻量。

最近在做的一个项目采用了EntityFramework4.3 Code First 模式开发,希望引入这个组件完成日志跟踪和缓存功能。

在网上搜寻EFProviderWrappers 相关资料基本上都是基于ObjectContext而不是DbContext。而且这个组件也没有更新,最新版本也是2011年4月。

有什么方法才能在EF4上正常使用呢?

现将研究的方法总结一下

  1.  首先是下载这套组件EFProviderWrapperToolKit
  2. 在项目中引用EFProviderWrapperToolkit.dll、EFTracingProvider.dll和  EFCachingProvider.dll 
  3. 在Web.Config 或App.Config配置文件中增加配置节

 

<connectionStrings>                                            

     <add name="TestContext"          

             providerName="System.Data.SqlClient"          

             connectionString="Server=Wyd\Instance;Initial Catalog=DatabaseName;User ID=sa;Password=123;MultipleActiveResultSets=True"/>

</connectionStrings>

<system.data>

      <DbProviderFactories>

             <add name="EF Caching Data Provider"             

                      invariant="EFCachingProvider"

                      description="Caching Provider Wrapper"                                                type="EFCachingProvider.EFCachingProviderFactory, EFCachingProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=def642f226e0e59b"/>

             <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>

4.在DbContext类中 建立两个构造方法(这就是关键处了)

 

 1 public class TestContext : DbContext
 2 {
 3    public TestContext() 
 4    { 
 5    }   
 6    public TestContext(DbConnection conn)
 7         :Base(conn,True) 
 8    { 
 9    }
10 } 

 5.  OverLoad the DbConnection.

1 using (var context = new TextContext(CreateConnectionWrapper(@"name=TestContext"))) 
2 {                  
3     var product = context.ProductCollection.Find(1);             
4 }
6. 添加CreateConnectionWrapper 方法
private static DbConnection CreateConnectionWrapper(string nameOrConnectionString) 
{     
   var providerInvariantName ="System.Data.SqlClient";     
   var connectionString = nameOrConnectionString;     //name=connectionName format     
   var index = nameOrConnectionString.IndexOf('=');     
   if (nameOrConnectionString.Substring(0,index).Trim().Equals("name", StringComparison.OrdinalIgnoreCase))     
   {
       nameOrConnectionString=nameOrConnectionString.Substring(index + 1).Trim();     
   }     
   //look up connection string name     
   var connectionStringSetting = ConfigurationManager.ConnectionStrings[nameOrConnectionString];     
   if (connectionStringSetting != null)     
   {         
       providerInvariantName = connectionStringSetting.ProviderName;
             connectionString = connectionStringSetting.ConnectionString;     
      }     
      //create the special connection string with the provider name in it     
      var wrappedConnectionString = wrappedProvider=" + providerInvariantName + ";" + connectionString;     
      //create the tracing wrapper     
      var connection = new EFTracingConnection                            
      {                                    
           ConnectionString = wrappedConnectionString                              };     
      //写日志logging

      connection.CommandFinished += (sender, args) => Console.WriteLine(args.ToTraceString());    

      return connection; 

 posted on 2012-06-08 15:24  王育东  阅读(3101)  评论(5编辑  收藏  举报