Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The specified cast from a materialized 'System.Guid' type to the 'System.Int32' type is not valid

The specified cast from a materialized 'System.Guid' type to the 'System.Int32' type is not valid.

We have several WCF services that have concurrency mode of Multiple and InstanceContextMode of Single. Our architecture focuses on a loosely coupled model using constructor-based dependency injection. This in turn is implemented using Unity 2.0 (web.config of each service has mappings between interfaces and types defined in a unity container section). One of our dependencies is a DAL assembly (data access layer) that uses Entity Framework 4 to communicate with MSSql Server. The classes that do the talking to the database are also included in the unity mapping.

Everything is great when we run our integration tests. But when we move to our performance environment to run load tests (2, 3, 4 concurrent users) we start seeing the following error:

System.InvalidOperationException: The 'auth_token' property on 'Session' could not be set to a 'Int32' value. You must set this property to a non-null value of type 'Guid'.

With the following stack:

at System.Data.Common.Internal.Materialization.Shaper.ErrorHandlingValueReader`1.GetValue(DbDataReader reader, Int32 ordinal)
at System.Data.Common.Internal.Materialization.Shaper.GetPropertyValueWithErrorHandling[TProperty](Int32 ordinal, String propertyName, String typeName)
at lambda_method(Closure , Shaper )
at System.Data.Common.Internal.Materialization.Shaper.HandleEntityAppendOnly[TEntity](Func`2 constructEntityDelegate, EntityKey entityKey, EntitySet entitySet)
at lambda_method(Closure , Shaper )
at System.Data.Common.Internal.Materialization.Coordinator`1.ReadNextElement(Shaper shaper)
at System.Data.Common.Internal.Materialization.Shaper`1.SimpleEnumerator.MoveNext()
at System.Linq.Enumerable.First[TSource](IEnumerable`1 source)
at System.Linq.Queryable.First[TSource](IQueryable`1 source)
at MISoa.DataAccessLayer.Authentication.AuthenticationDB.RetrieveSession(Guid authToken)
at MISoa.DataAccessLayer.Authentication.AuthenticationAccess.RetrieveSession(String sessionToken)

Here is the culprit method:

public Session RetrieveSession(Guid authToken)
    {
        CheckDBContext();
        var sessions = (from r in _dbContext.Sessions
                where r.auth_token == authToken
                select r);
        return sessions.Count() > 0 ? sessions.First() : null;
    }

CheckDBContext method simply checks if the db context is null and, if it is, it throws a custom exception.

The emdx Session entity object has these public properties:

Guid auth_token
DateTime time_stamp
String user_id
String app_id

So, it looks like sometimes the above linq returns some other object from the database where the first column is an int and not a guid? And if so - why? Do I have a problem with multiple threads overriding each other's db context? BTW - we abstracted the code that instantiates the db context to a separate class (BaseDB) which is also handled by unity. So, because the service is a singleton I have one instance of BaseDB for everyone, right? Is this the problem here?

Oh, one more thing. We were told that we will have MSSql 2005 so in the edmx file we have ProviderManifestToken="2005". But I just checked and the server with our performance database is version 2008. Is this a problem?

Thank you for your help.

like image 511
Rich Rosiak Avatar asked May 10 '12 20:05

Rich Rosiak


1 Answers

Do I have a problem with multiple threads overriding each other's db context?

Yes. See here: http://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.aspx

Quote from the big yellow box in the above link:

The ObjectContext class is not thread safe. The integrity of data objects in an ObjectContext cannot be ensured in multithreaded scenarios.

You may want to consider putting [ThreadStaticAttribute] on your _dbContext field.

like image 149
RobSiklos Avatar answered Oct 19 '22 06:10

RobSiklos