Tracing and Caching Provider Wrappers for Entity Framework

This sample hows how to extend Entity Framework in interesting ways by plugging into ADO.NET provider interface.

C# (1.9 MB)
 
 
 
 
 
(26)
18,452 times
Add to favorites
3/17/2011
E-mail Twitter del.icio.us Digg Facebook
Sign in to ask a question


  • how to use this for EF 5 code first?
    1 Posts | Last post September 22, 2012
    • i have setup everything correct. but command events not getting called. anything else to be done?
  • EFTracingProvider.EFTracingProviderFactory not created?
    1 Posts | Last post September 22, 2012
    • app.config contains below values, but still EFTracingProviderFactory not getting called any reason?
      
      
      <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=b77a5c561934e089" />
            <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>
      
      
  • DbFunctionCommandTree support?
    1 Posts | Last post August 21, 2012
    • Does the wrapper not support SPROC calls (Functions)? I receive this error when executing an imported function on an entity when using the wrapper:
      
      System.NotSupportedException was unhandled by user code
        Message=Command tree type System.Data.Common.CommandTrees.DbFunctionCommandTree is not supported.
        Source=EFCachingProvider
        StackTrace:
             at EFCachingProvider.EFCachingCommandDefinition.GetAffectedEntitySets(DbCommandTree commandTree)
             at EFCachingProvider.EFCachingCommandDefinition..ctor(DbCommandDefinition wrappedCommandDefinition, DbCommandTree commandTree)
             at EFCachingProvider.EFCachingProviderServices.CreateCommandDefinitionWrapper(DbCommandDefinition wrappedCommandDefinition, DbCommandTree commandTree)
             at EFProviderWrapperToolkit.DbProviderServicesBase.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree)
             at System.Data.Common.DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree)
             at System.Data.EntityClient.EntityCommandDefinition..ctor(DbProviderFactory storeProviderFactory, DbCommandTree commandTree)
        InnerException: 
      
  • MVC3 example of Caching using IDbConnectionFactory on Codeplex
    1 Posts | Last post August 07, 2012
    • Hi, 
      
      I posted an example of how to use the Connection Factory to inject an EFCachingConnection on Codeproject, source code and article is available here
      
      http://www.codeproject.com/Articles/435142/Entity-Framework-Second-Level-Caching-with-DbConte
      
      Partly inspired by the post from 'martin w' in this thread and the realisation I could override the connection factory with a custom implementation
  • Support in EF DbContext
    4 Posts | Last post July 28, 2012
    • I have a solution to support those provider to run in EF DbContext. Details as follow:
      
      1. Extends methods to DbContext 
      
      ---------------------------------------------
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Data.Common;
      using System.Data.Entity.Infrastructure;
      using System.Data.Entity;
      
      namespace EFProviderWrapperToolkit
      {
          public static class EFProviderWriterDbContextExtensionMethods
          {
              /// <summary>
              /// Gets the underlying wrapper connection from the <see cref="DbContext"/>.
              /// </summary>
              /// <typeparam name="TConnection">Connection type.</typeparam>
              /// <param name="context">The db context.</param>
              /// <returns>Wrapper connection of a given type.</returns>
              [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "Type parameter must be specified explicitly.")]
              public static TConnection UnwrapConnection<TConnection>(this DbContext context)
                  where TConnection : DbConnection
              {
                  if (context == null)
                  {
                      throw new ArgumentNullException("context");
                  }
      
                  return ((IObjectContextAdapter)context).ObjectContext.Connection.UnwrapConnection<TConnection>();
              }
      
      
    • continue as follows:
      ----------------------------------------------------
      /// <summary>
              /// Tries to get the underlying wrapper connection from the <see cref="DbContext"/>.
              /// </summary>
              /// <typeparam name="TConnection">Connection type.</typeparam>
              /// <param name="context">The db context.</param>
              /// <param name="result">The result connection.</param>
              /// <returns>A value of true if the given connection type was found in the provider chain, false otherwise.</returns>
              public static bool TryUnwrapConnection<TConnection>(this DbContext context, out TConnection result) where TConnection : DbConnection
              {
                  if (context == null)
                  {
                      throw new ArgumentNullException("context");
                  }
      
                  return ((IObjectContextAdapter)context).ObjectContext.Connection.TryUnwrapConnection<TConnection>(out result);
              }
          }
      }
    • continue:
      
      2. Should reference EntityFramework.dll from old ObjectContext to DbContext version.
      For me, it is the newest one version 4.4.0.0
      
      Important: follows projects should change the EntityFramework reference file:
      (1) EFProviderWrapperToolkit
      (2) EFProviderWrapperDemo
      
      3. Now you can run EFProviderWrapperDemo.
      
      Have any question please follow this thread. Maybe I miss something.
    • continue
      
      forget another important:
      
      public partial class NorthwindEFEntities
          {
              public NorthwindEFEntities(DbConnection dbConnect, bool contextOwnsConnection)
                  : base(dbConnect, contextOwnsConnection)
              {
                  this.Configuration.ProxyCreationEnabled = false;
              }
          }
  • Logging all available connections without deriving contexts
    1 Posts | Last post July 25, 2012
    • Hi,
      
      First of all, thanks for your work !!! it's really handy to check bottlenecks and avoid them !
      
      My first question is : is it possible to avoid the use of a derived class instead of the original context ? I've seen that the EF Profiler application doesn't need to have any information about contexts in the application. You just have to call an Initialize method (without parameter) and it will trace all EF contexts of your application.
      Is there a way to do that ?
      
      Second question : what about performances using tracing into a production application ? We would like to monitor our application in real time to be as reactive as possible. So I think I will use EF Tracing to check execution time and if it is superior to a constant of time, it will raise an alert. Do you think that it is a bad or a good idea to use this in production mode?
      
      Regards,
      
      Steeve
  • Any Chance of getting EF Code First 4.3 Example posted
    4 Posts | Last post July 17, 2012
    • It would be very helpful if there was a codefirst 4.3 example posted for using both Cache and Trace
    • Use the DbCommand constructor overload in your DbContext...
      var context = new NorthwindContext(CreateConnectionWrapper(@"name=NorthwindContext"));
      
      And the CreateConnectionWrapper method:
      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
                                  };
          //hook up logging here
          connection.CommandFinished +=
              (sender, args) => Console.WriteLine(args.ToTraceString());
          return connection;
      }
      
      This just does the TracingWrapper, but you can also wrap the Caching wrapper in the same way.
      
      
    • hello martin w ,i accept your suggestion and use this method in cache and i only modify the line "var connection = new EFTracingConnection" to "var connection = new EFCachingConnection" and the following line don't need "connection.CommandFinished +=
              (sender, args) => Console.WriteLine(args.ToTraceString());"  but which class should need add this method?? and weather the way to use this method is right? how can i use this method in this way ? new “NorthwindContext(CreateConnectionWrapper(@"name=NorthwindContext"));” the method is "staitc " so it need className to use it like"NorthwindContext(NotrthwindContenx.CreateConnectionWrapper(@"name=NorthwindContext"));"  我的英文不太好,翻译一下:
      我用了martin w 的建议,然后修改了“var connection = new EFTracingConnection”这行,改成了“var connection = new EFCachingConnection”下面两行是不要的。但是我把这个方法放到哪个类中呢?而且这个方法是static的方法,我调用的时候,怎么可以使用这种方法呢?至少得有个类名吧?怎么才能直接调用这个方法名呢?
    • i hope anybody can give me an answer.thank you
  • Connection string not in app.config: store provider exception
    1 Posts | Last post June 29, 2012
    • I am trying to use the tracing provider in an application where contexts are initialized by passing the connection string in the constructor. (sql2008, EF 4.3.1 database first). When I enhance the context the way it is shown in the code sample I get an exception: The specified store provider cannot be found in the configuration, or is not valid. (In EntityConnectionWrapperUtils.CreateWrappedMetadataWorkspace in the constructor of StoreItemCollection).
      
      What can I do? I want to keep working with "injected" connection strings, because there already is a non-EF connection string in the app.config which should be the only one.
  • Thread safety
    1 Posts | Last post May 08, 2012
    • Creating multiple context's at the same time results into "A item with the same key already has been added".
      
      It happens in the static method CreateEntityConnectionWithWrappers when a wrappedMetadataWorkspace is being constructed and it hasn't been add to the metadataWorkspace fast enough and another thread is doing the same.
      
      I fixed it in the static method of EntityConnectionWrapperUtils by locking the metadataWorkspaceMemoizer.
      
      Another possible fix would be to check if the connectionstring is already added in the metadataWorkspacemeMemoizer.
  • Unsupported CreateDbCommand
    5 Posts | Last post March 23, 2012
    • Hi, this is great code! I am using it to trace my EF queries to the database and make sure the proper SQL is generated for performance reasons during development only. 
      
      I just use the Tracing Provider and wonder what are the reasons that the CreateDBCommand is not supported? Because of this, directly executing store commands using methods such as ObjectContext.ExecuteStoreCommand or ObjectContext.ExecuteStoreQuery is not supported. Now I understand that it may be more complicated to trace or cache in this case, but I am not particularly interested in tracing the output of my direct store command, as I already know what I wrote in the query :) 
      
      So I just changed the code in DbConnectionWrapper.cs from:
      
      protected override DbCommand CreateDbCommand() 
      { 
          throw new NotSupportedException(); 
      } 
      
      to:
      
      protected override DbCommand CreateDbCommand() 
      { 
          return this.wrappedConnection.CreateDbCommand();
      } 
      
      Do you think this would cause issues somewhere else in the toolkit, like improper disposing of resources or similar? Is this approach ok considering what I stated above and not needing the extended functionality for this particular case?
      
      Thank you!
    • I'm interested in the answer to this question... I'm about to do the same myself.
    • I had the exact same problem and made the same change as you. I mentioned this to Kowalski back last November http://jkowalski.com/2010/05/24/update-to-efproviderwrappers-is-available/ but have got no feedback. I notice that he also doesnt appear to be very active in this forum so i suppose we are on our own to work it out. So far i dont think i have had any major memory issues but im not 100% sure myself.
    • Create a class,
       public class DbTracingConnection : EFTracingConnection
          {
              protected override DbCommand CreateDbCommand()
              {
                  return this.WrappedConnection.CreateCommand();
              }
          }
      
      
    • I too performed the same change and everything seems to work but the caching support is not there for DbCommands, which is unfortunate. Any chance this could get implemented?
11 - 20 of 41 Items