Home
Help
Register
Log in

Search

 
   Active Threads  

You are here: Home > ORM Profiler Section > Bugs & Issues> Ignore calls to other ORM
 

Pages: 1
Bugs & Issues
Ignore calls to other ORM
Page:1/1 

  Print all messages in this thread  
Poster Message
speed2002
User



Location:

Joined on:
07-Apr-2014 11:23:51
Posted:
7 posts
# Posted on: 07-Apr-2014 11:26:37.  
Hi

Is there a way to totally ignore calls to other ORM's?

I also use NetTiers in our Application and i always get cast errors like this:

Unable to cast object of type 'SD.Tools.OrmProfiler.Interceptor.ProfilerDbConnection' to type 'System.Data.SqlClient.SqlConnection'.

in the following Code Section:

            InterceptorCore.BeginIgnoredSection();
            _serviceBenutzerSitzung.CreateSession(user.Id, SecuritySettings.UserSessionTimeout, ref sessionAlreadyExists, ref _sessionId);
            InterceptorCore.EndIgnoredSection();

Thanks for your help..

kind regards
michael
  Top
Otis
ORM Profiler Team



Location:
The Hague, The Netherlands
Joined on:
22-Aug-2011 10:26:38
Posted:
611 posts
# Posted on: 07-Apr-2014 16:13:19.  
I don't know nettiers internals, so do you pass a connection to it or does it use the factory system? Because if it uses the factory system (DbProviderFactory) it should work ok, so it might be you pass a sqlconnection instance somewhere? (or that's created somewhere) ?

Frans Bouma
ORM Profiler / LLBLGen Pro Lead Developer | Blog | Twitter
 
Top
speed2002
User



Location:

Joined on:
07-Apr-2014 11:23:51
Posted:
7 posts
# Posted on: 07-Apr-2014 16:19:52.  
Hmm, not sure about that, but actually i don't want to profile these DB Calls. I switched to LLBLGen and just want to profile these queries.

The best solution for me would be if there is a property to ignore the profiler exceptions. All queries that are working should be profiled the others not. My Software has so many queries that its nearly impossible to get where i want to without a special query that let the orm profiler crash.

Is there somesthing like this in the profiler inception classes?

Thank you
  Top
Otis
ORM Profiler Team



Location:
The Hague, The Netherlands
Joined on:
22-Aug-2011 10:26:38
Posted:
611 posts
# Posted on: 07-Apr-2014 18:11:04.  
The thing is: the Begin/endIgnoredSection() calls simply stop the messaging to the named pipe, they don't reset the DbProviderFactory table in .NET.

This means that as soon as you call initialize on the interceptorcore, the DbProviderFactory table will be overwritten with the wrapper factories and they'll produce wrapped objects for DbConnection, DbCommand etc.

This goes wrong if data access code assumes a given type, e.g. SqlConnection, while it got a ProfilerDbConnection which wraps the SqlConnection. This is the case in code which e.g. uses a specific class for a given Db and thus assumes that the objects inside the class are of a given type (e.g. a 'sql server' specific class assumes all used objects are of sqlclient, not DbConnection, DbCommand etc.)

The problem is that once the DbProviderFactory table is overwritten, it will produce always the wrapper objects, as it's a central static table so all code in the appdomain will use it.

The exceptions aren't inside the profiler, they're inside the data access code: it crashes because it assumes it works with a typed connection/command (e.g. SqlConnection) while it got a different object. This can happen if the data access code does things like:

var factory = <get SqlClient factory>;
var connection = (SqlConnection)factory.CreateConnection();

this code normally works fine, however it fails when the factory table is overwritten: the CreateConnection() call will now create a wrapper for the connection created so won't be of type SqlConnection and thus the cast crashes, and you'll see the exception like you saw.

As you didn't give the stacktrace, I assume this is the case. If the stack trace shows it's somewhere inside our code, we'll of course have a look at it. Regular Smiley So if you could post the stacktrace that would be great Regular Smiley

The reason I asked whether you pass the connection object is meant to make the code work, so you don't get these exceptions. Unfortunately, because the dbproviderfactory table is a static resource in an appdomain, overwriting it is therefore a thing that affects all code in an appdomain, so all code using that table. And as it's a static resource we can't overwrite it back in an ignored section as another thread might still be doing profiling work.


Frans Bouma
ORM Profiler / LLBLGen Pro Lead Developer | Blog | Twitter
 
Top
speed2002
User



Location:

Joined on:
07-Apr-2014 11:23:51
Posted:
7 posts
# Posted on: 08-Apr-2014 08:19:18.  
Wow, thank you very much for this great answer. I now totally understand the problem and will research a bit in the generated nettiers code. I will keep you updated.
  Top
speed2002
User



Location:

Joined on:
07-Apr-2014 11:23:51
Posted:
7 posts
# Posted on: 08-Apr-2014 09:49:12.  
Here is the StackTrace of the Exception:

Unable to cast object of type 'SD.Tools.OrmProfiler.Interceptor.ProfilerDbConnection' to type 'System.Data.SqlClient.SqlConnection'.

at System.Data.SqlClient.SqlCommand.set_DbConnection(DbConnection value)
at System.Data.Common.DbCommand.set_Connection(DbConnection value)
at Microsoft.Practices.EnterpriseLibrary.Data.Database.PrepareCommand(DbCommand command, DbConnection connection)
at Microsoft.Practices.EnterpriseLibrary.Data.Database.PrepareCommand(DbCommand command, DbTransaction transaction)
at Microsoft.Practices.EnterpriseLibrary.Data.Database.ExecuteNonQuery(DbCommand command, DbTransaction transaction)
at B2.Data.Utility.ExecuteNonQuery(TransactionManager transactionManager, DbCommand dbCommand)


  Top
Otis
ORM Profiler Team



Location:
The Hague, The Netherlands
Joined on:
22-Aug-2011 10:26:38
Posted:
611 posts
# Posted on: 08-Apr-2014 10:46:38.  
That's the full stack trace or are there calls before the B2.Data call? The reason I ask is that the exception occurs inside the SqlCommand object, where it's assigned to a DbConnection. It expects it to be a SqlConnection, but it's a wrapped connection so it fails. The core issue is where the SqlCommand is created: it should either use the DbConnection (the wrapper one) to create a command, or use the factory but I fear it simply uses new SqlCommand()...

Nettiers, is that the one at nettiers.net ? I'll see if I can get it to work and where it might be causing problems. perhaps there's a way around it Regular Smiley
Frans Bouma
ORM Profiler / LLBLGen Pro Lead Developer | Blog | Twitter
 
Top
speed2002
User



Location:

Joined on:
07-Apr-2014 11:23:51
Posted:
7 posts
# Posted on: 08-Apr-2014 11:07:03.  
Yes exactly..

I found the following workaround to exclude NetTiers queries so far:

Inside the TransactionManager class are several calls to the DbProviderFactory which returns the Wrapper.

Code:
        /// <summary>
        ///    Initializes a new instance of the <see cref="TransactionManager"/> class.
        /// </summary>
        /// <param name="connectionString">The connection string to the database.</param>
        /// <param name="providerInvariantName">Name of the provider invariant.</param>
        public TransactionManager( string connectionString, string providerInvariantName )
        {
            this._connectionString = connectionString;
            this._invariantProviderName = providerInvariantName;
            this._database = new GenericDatabase(_connectionString, DbProviderFactories.GetFactory( this._invariantProviderName ) );
            this._connection = this._database.CreateConnection();
        }


So by replacing these calls
Code:

DbProviderFactories.GetFactory( this._invariantProviderName )

with the singleton instance of the SqlClientFactory
Code:

System.Data.SqlClient.SqlClientFactory.Instance

I can solve my initial problem. But i will research some more if i can get it to work even with the wrapper classes.


  Top
speed2002
User



Location:

Joined on:
07-Apr-2014 11:23:51
Posted:
7 posts
# Posted on: 08-Apr-2014 11:48:13.  
OK, i think i got the problem:

Code:

public override void CreateSession(TransactionManager transactionManager, int start, int pageLength , System.Int32 benutzerId, System.Int32 sessionTimeout, ref System.Boolean sessionAlreadyExists, ref System.Guid sessionId)
        {
            SqlDatabase database = new SqlDatabase(this._connectionString);
            DbCommand commandWrapper = StoredProcedureProvider.GetCommandWrapper(database, "dbo._BenutzerSitzung_CreateSession", true);


Inside the generated stored procedure code there is a new SqlDatabase object instantiated. I think thats the problem, right?

I think we should use the Database object of the TransactionManager we already have at this point. I'll try that...
  Top
speed2002
User



Location:

Joined on:
07-Apr-2014 11:23:51
Posted:
7 posts
# Posted on: 08-Apr-2014 14:26:24.  
Soo, finally i got it...

I had to replace all the lines

Code:

SqlDatabase database = new SqlDatabase(this._connectionString);


with

Code:

Database database;
if(transactionManager != null)
    database = transactionManager.Database;
else
    database = new GenericDatabase(this._connectionString, DbProviderFactories.GetFactory( this._providerInvariantName ) );


In the following template files:

Code:

Template\DataAccessLayer.SqlClient\SqlEntityProviderBase.generated.cst
Template\DataAccessLayer.SqlClient\Views\SqlEntityViewProviderBase.generated.cst


  Top
Otis
ORM Profiler Team



Location:
The Hague, The Netherlands
Joined on:
22-Aug-2011 10:26:38
Posted:
611 posts
# Posted on: 08-Apr-2014 19:25:08.  
excellent work! Regular Smiley From the looks of it, it also will make it possible to intercept nettiers queries (if you still use them).
Frans Bouma
ORM Profiler / LLBLGen Pro Lead Developer | Blog | Twitter
 
Top
Pages: 1  


Powered by HnD ©2002-2007 Solutions Design
HnD uses LLBLGen Pro

Version: 2.1.09082011 Final.