|
|
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.Com mon.CommandTree s.DbFunctionCom mandTree is not supported. Source=EFCachin gProvider StackTrace: at EFCachingProvid er.EFCachingCom mandDefinition. GetAffectedEnti tySets(DbComman dTree commandTree) at EFCachingProvid er.EFCachingCom mandDefinition. .ctor(DbCommand Definition wrappedCommandD efinition, DbCommandTree commandTree) at EFCachingProvid er.EFCachingPro viderServices.C reateCommandDef initionWrapper( DbCommandDefini tion wrappedCommandD efinition, DbCommandTree commandTree) at EFProviderWrapp erToolkit.DbPro viderServicesBa se.CreateDbComm andDefinition(D bProviderManife st providerManifes t, DbCommandTree commandTree) at System.Data.Com mon.DbProviderS ervices.CreateC ommandDefinitio n(DbCommandTree commandTree) at System.Data.Ent ityClient.Entit yCommandDefinit ion..ctor(DbPro viderFactory storeProviderFa ctory, DbCommandTree commandTree) InnerException:
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.code project.com/Art icles/435142/En tity-Framework- Second-Level-Ca ching-with-DbCo nte Partly inspired by the post from 'martin w' in this thread and the realisation I could override the connection factory with a custom implementation
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.Collecti ons.Generic; using System.Linq; using System.Text; using System.Data.Com mon; using System.Data.Ent ity.Infrastruct ure; using System.Data.Ent ity; namespace EFProviderWrapp erToolkit { public static class EFProviderWrite rDbContextExten sionMethods { /// <summary> /// Gets the underlying wrapper connection from the <see cref="DbContext "/>. /// </summary> /// <typeparam name="TConnecti on">Connection type.</typepara m> /// <param name="context"> The db context.</param > /// <returns>Wrappe r connection of a given type.</returns> [System.Diagnos tics.CodeAnalys is.SuppressMess age("Microsoft. Design", "CA1004:Generic MethodsShouldPr ovideTypeParame ter", Justification = "Type parameter must be specified explicitly.")] public static TConnection UnwrapConnectio n<TConnection>( this DbContext context) where TConnection : DbConnection { if (context == null) { throw new ArgumentNullExc eption("context "); } return ((IObjectContex tAdapter)contex t).ObjectContex t.Connection.Un wrapConnection< TConnection>(); }
continue as follows: ------------------------------ --------------- ------- /// <summary> /// Tries to get the underlying wrapper connection from the <see cref="DbContext "/>. /// </summary> /// <typeparam name="TConnecti on">Connection type.</typepara m> /// <param name="context"> The db context.</param > /// <param name="result">T he result connection.</pa ram> /// <returns>A value of true if the given connection type was found in the provider chain, false otherwise.</ret urns> public static bool TryUnwrapConnec tion<TConnectio n>(this DbContext context, out TConnection result) where TConnection : DbConnection { if (context == null) { throw new ArgumentNullExc eption("context "); } return ((IObjectContex tAdapter)contex t).ObjectContex t.Connection.Tr yUnwrapConnecti on<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) EFProviderWrapp erToolkit (2) EFProviderWrapp erDemo 3. Now you can run EFProviderWrapp erDemo. Have any question please follow this thread. Maybe I miss something.
continue forget another important: public partial class NorthwindEFEntities { public NorthwindEFEnti ties(DbConnecti on dbConnect, bool contextOwnsConn ection) : base(dbConnect, contextOwnsConn ection) { this.Configurat ion.ProxyCreati onEnabled = false; } }
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
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(CreateConnect ionWrapper(@"na me=NorthwindCon text")); And the CreateConnectio nWrapper method: private static DbConnection CreateConnectio nWrapper(string nameOrConnectio nString) { var providerInvaria ntName = "System.Data.Sq lClient"; var connectionStrin g = nameOrConnectio nString; //name=connecti onName format var index = nameOrConnectio nString.IndexOf ('='); if (nameOrConnecti onString.Substr ing(0, index).Trim() .Equals("name", StringCompariso n.OrdinalIgnore Case)) { nameOrConnectio nString = nameOrConnectio nString .Substring(inde x + 1).Trim(); } //look up connection string name var connectionStrin gSetting = ConfigurationMa nager.Connectio nStrings[nameOr ConnectionStrin g]; if (connectionStri ngSetting != null) { providerInvaria ntName = connectionStrin gSetting.Provid erName; connectionStrin g = connectionStrin gSetting.Connec tionString; } //create the special connection string with the provider name in it var wrappedConnecti onString = "wrappedProvide r=" + providerInvaria ntName + ";" + connectionStrin g; //create the tracing wrapper var connection = new EFTracingConnec tion { ConnectionStrin g = wrappedConnecti onString }; //hook up logging here connection.Comm andFinished += (sender, args) => Console.WriteLi ne(args.ToTrace String()); 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 EFCachingConnec tion" and the following line don't need "connection.Com mandFinished += (sender, args) => Console.WriteLi ne(args.ToTrace String());" 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 “NorthwindConte xt(CreateConnec tionWrapper(@"n ame=NorthwindCo ntext"));” the method is "staitc " so it need className to use it like"NorthwindC ontext(Notrthwi ndContenx.Creat eConnectionWrap per(@"name=Nort hwindContext")) ;" 我的英文不太好,翻译一下: 我用了martin w 的建议,然后修改了“var connection = new EFTracingConnec tion”这行,改成了“var connection = new EFCachingConnec tion”下面两行是不要的。但 是我把这个方法放到哪个类中呢? 而且这个方法是static的方 法,我调用的时候,怎么可以使用 这种方法呢?至少得有个类名吧? 怎么才能直接调用这个方法名呢?
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.C reateWrappedMet adataWorkspace in the constructor of StoreItemCollec tion). 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.
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 CreateEntityConnectionWithWrap pers when a wrappedMetadata Workspace is being constructed and it hasn't been add to the metadataWorkspa ce fast enough and another thread is doing the same. I fixed it in the static method of EntityConnectio nWrapperUtils by locking the metadataWorkspa ceMemoizer. Another possible fix would be to check if the connectionstrin g is already added in the metadataWorkspa cemeMemoizer.
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.ExecuteStoreComm and or ObjectContext.E xecuteStoreQuer y 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 DbConnectionWra pper.cs from: protected override DbCommand CreateDbCommand () { throw new NotSupportedExc eption(); } to: protected override DbCommand CreateDbCommand () { return this.wrappedCon nection.CreateD bCommand(); } 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/2 4/update-to-efp roviderwrappers -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 : EFTracingConnec tion { protected override DbCommand CreateDbCommand () { return this.WrappedCon nection.CreateC ommand(); } }
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?
Hello, Is there any way to make this work together with the Hibernating Rhinos Profiler? Upon calling "EntityConnectionWrapperUtils. CreateEntityCon nectionWithWrap pers" I get this exception: Das Objekt des Typs "HibernatingRhi nos.Profiler.Ap pender.Profiled DataAccess.Prof iledConnection" kann nicht in Typ "EFProviderWrap perToolkit.DbCo nnectionWrapper " umgewandelt werden. (Sorry, german, it can't cast one type into another.)
I have some parallel tasks that used the wrapper. They all create their own context to use, but EntityConnectionWrapperUtils.C reateEntityConn ectionWithWrapp ers breaks because metadataWorkspa ceMemoizer.TryG etValue initially returns false. Since the code is running in separate tasks one task finishes creating the workspace and adds it to the metadataWorkspa ceMemoizer 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 ConcurrentDicti onary 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.