Microsoft Developer Network > Samples >
Tracing and Caching Provider Wrappers for Entity Framework

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.


Select a language
 
 
 
 
 
(13)
4,641 times
3/17/2011
E-mail Twitter del.icio.us Digg Facebook
Add To Favorites
Description
Browse Code
Q and A (22)
C#
Sign in to Ask a Question


  • Appears not to be thread safe
    2 Posts | Last Post February 13, 2012
    • I have some parallel tasks that used the wrapper. They all create their own context to use, but EntityConnectionWrapperUtils.CreateEntityConnectionWithWrappers breaks because metadataWorkspaceMemoizer.TryGetValue initially returns false. Since the code is running in separate tasks one task finishes creating the workspace and adds it to the metadataWorkspaceMemoizer before the others. When the next task finishes creating the workspace and attempts to add it to the dictionary there is an exception thrown because the an item with that key already exists.
      
      To fix it I changed the Dictionary to a ConcurrentDictionary and the Add to a TryAdd. After that it works as far as I can see (I've not tested it extensively, but it no longer seems to collide). Howerver, there are probably more efficient ways of doing this that don't involve creating workspaces that get thrown away.
    • @Colin I sometimes get the same error when many users first hit my web application at once, which uses this.
  • Exception NotSupportedException on IIS Pool refresh
    1 Posts | Last Post January 19, 2012
    • Hi, 
      
      I use the TracingProvider on my project and it works fine at the first launch, but after a long inactivity time (the night !), I've the folowwing error :
      
      Exception message: The invoked member is not supported in a dynamic assembly.
         at System.Reflection.Emit.InternalAssemblyBuilder.GetManifestResourceStream(String name)
         at EFProviderWrapperToolkit.EntityConnectionWrapperUtils.ParseResources(String resPath, List`1 csdl, List`1 ssdl, List`1 msl)
         at EFProviderWrapperToolkit.EntityConnectionWrapperUtils.ParseMetadata(String metadata, List`1 csdl, List`1 ssdl, List`1 msl)
         at EFProviderWrapperToolkit.EntityConnectionWrapperUtils.CreateWrappedMetadataWorkspace(String metadata, IEnumerable`1 wrapperProviderNames)
         at EFProviderWrapperToolkit.EntityConnectionWrapperUtils.CreateEntityConnectionWithWrappers(String entityConnectionString, String[] wrapperProviders)
         at Kheops.Dal.EntitiesWithLog..ctor(String connectionString)
      
      After analysis I modified the EntityConnectionWrapperUtils (line 185, add !asm.IsDynamic) :
      
      foreach (Assembly asm in assembliesToConsider.Where(asm => !IsEcmaAssembly(asm) && !IsSystemAssembly(asm) && !asm.IsDynamic))
      
      And now it works fine !
      
      Thanks for this wrapper.
      
  • Unsupported CreateDbCommand
    4 Posts | Last Post January 16, 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();
              }
          }
      
      
  • DbTransactionWrapper and Transactionscope
    3 Posts | Last Post January 12, 2012
    • Hi,
      
      Following on from my previous question - when I wrap the sample project in a "Transactionscope", the DbTransactionWrapper is not created (this is using both wrappers - the caching and tracing).  Although a transaction is being created and committed to the database, I am unsure how I can trace the Transactions created with a "Transactionscope".
      
      Can you advise as to how I can trace Transactions in the EF created using a Transactionscope?
      
      Than you again for your input,
      
      Jack
    • I think it is worse than that when it comes to caching. I have data committed to the database inside a TransactionScope and the whole cache clearing mechanism that clears out cached data for affected tables is bypassed.  The end result is my committed data can't be seen on the next screen when it does a select.
      
      Is there a fix for this or a workaround where I can invalidate the cache for the tables I know have been affected?
    • To work around the issue I had to update the code in the EFCachingCommand.UpdateAffectedEntitySets method to the following:
      
              private void UpdateAffectedEntitySets()
              {
                  // Sometimes the transaction field is null
                  // (usually when transaction context has been set explicitly).
                  // So the changes are not registered and cache not refreshed
                  if (this.transaction != null)
                  {
                      if (this.Definition.IsModification)
                      {
                          this.transaction.HasModifications = true;
                      }
      
                      foreach (EntitySetBase entitySet in this.Definition.AffectedEntitySets)
                      {
                          this.transaction.AddAffectedEntitySet(entitySet);
                      }
                  }
                  else if (this.Definition.IsModification)
                  {
                      // As workaround to above, invalidate cache right away.
                      var cache = this.Connection.Cache;
                      if (cache != null)
                      {
                          cache.InvalidateSets(this.Definition.AffectedEntitySets.Select(s => s.Name));
                      }
                  }
              }
      
  • Code First Entity Framework 4.1
    5 Posts | Last Post December 22, 2011
    • Are there any plans to update this to work with Entity Framework 4.1 Code-first? The wrapper fails to create the database when wrapping System.Data.SqlClient
    • i have the same question,how should i to do?
    • I also would like to know if this will be updated to work with EF 4.1 Code First.
      Currently I tried to create a connection like so:
      
      var factory = DbProviderFactories.GetFactory("EFCachingProvider");
                  var wrapper = (DbConnectionWrapper)factory.CreateConnection();
                  wrapper.WrappedConnection = new SqlConnection(WebConfigurationManager.ConnectionStrings[ConnectionStringName].ConnectionString).;
                  return wrapper;
      
      However, as soon as I try to connect to the database using the wrapped connection I receive the following exception:
      
      Expecting non-empty string for 'providerInvariantName' parameter.
      
      Stack Trace: 
      
      Stack Trace: 
      
      
      
      
      
      [ArgumentException: Expecting non-empty string for 'providerInvariantName' parameter.]
         System.Data.Common.ADP.CheckArgumentLength(String value, String parameterName) +2011957
         System.Data.Common.DbProviderFactories.GetFactory(String providerInvariantName) +21
         EFProviderWrapperToolkit.DbProviderServicesBase.GetProviderServicesByName(String providerInvariantName) +13
         EFProviderWrapperToolkit.DbProviderServicesBase.GetDbProviderManifest(String manifestToken) +118
         System.Data.Common.DbProviderServices.GetProviderManifest(String manifestToken) +27
      
    • Same question, when will it be updated?
    • I have found a solution to make the providers work for EF 4.1 code first. See my blog here: http://tigerang.blogspot.com/2011/12/how-to-make-tracing-and-caching.html
      
      Cheers
      Hugh Ang
  • Not all requests go through caching provider
    1 Posts | Last Post November 29, 2011
    • It looks like some requests manage to bypass caching provider in EF 4.2 even though the caching policy is set to CacheAll. Although some requests - do cache. I can't find a pattern why query bypasses the cache but I definitely observe call to the EF context set resulting in the query to the database in the sql server profiler with no methods of the EFCachingCommand invoked.
      
      Can there be some overrides of the System.Data.Common.DbCommand class which are used by EF context but not overridden in the EFCachingCommand?
  • Cache expiration from second application
    2 Posts | Last Post September 06, 2011
    • I try to use the caching provider in our application with InMemoryCache (no ASP.NET), and it works great. The only issue is that our database also gets updated by a second and third application. Is there a way to let the cache in our primary application expire when there has been an insert or update from the 2nd or 3rd application? Or is there any other way to define the expiration criteria when using InMemoryCache?
      Hope that anybody can answer this question. 
      Thank you and kind regards, Jeroen
    • I have the same question. For now I created a button in my application that just sets the cache to new EFCachingProvider.Caching.InMemoryCache() whenever I want my data to refresh. If you figure out how to make this happen automatically please share your method. Thanks. 
  • How to enable Custom caching ?
    1 Posts | Last Post August 05, 2011
    • I have more than 500 entities, some of them with millions of records.
      I want to control which entities will be cached - how can I accomplish that ?
  • Caching Bug?
    1 Posts | Last Post July 29, 2011
    • I have found what I believe to be a bug and would like some input.
      I am using both tracing and caching successfully, but in some cases I don't want to cache.  For these instances, I create a new context with the CachingPolicy set to NoCaching.
      Now, when I use this context, it does appear to issue new SQL each time I query the context.  However, it appears to still be caching related data entities.  For example, assume I have a customer entity with related address entities.  If I (re)load the customers (and use .Include("Address") in LINQ), EVEN if the address has changed in the DB, the context continues to contain the OLD address.
      If I create a brand new context and run the same query this does not seem to be a problem.
      Any help?
      Appreciate it!!
  • Custom tracing only specified entities?
    1 Posts | Last Post July 26, 2011
    • Is it possible to have custom tracing that only traces certain entites (in the same way that custom caching can by done on a per entity basis)?
      
      Also, I have frequent exceptions when tracing is on: "The process cannot access the file 'C:\src\Logs\sqllog.txt' because it is being used by another process."  How can I fix this?
      
      Thanks
1 - 10 of 22 Items   
« First   < Prev   1  2  3    Next >   Last »