从物化的“System.Guid”类型到“System.Int32”类型的指定强制转换无效

时间:2012-05-10 20:59:48

标签: c# wcf sql-server-2008 sql-server-2005 entity-framework-4

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

我们有几个WCF服务,其并发模式为Multiple,InstanceContextMode为Single。我们的架构侧重于使用基于构造函数的依赖注入的松散耦合模型。这反过来是使用Unity 2.0实现的(每个服务的web.config都具有在统一容器部分中定义的接口和类型之间的映射)。我们的依赖项之一是使用Entity Framework 4与MSSql Server通信的DAL程序集(数据访问层)。与数据库通信的类也包含在单位映射中。

运行集成测试时,一切都很棒。但是当我们转移到我们的性能环境来运行负载测试(2,3,4个并发用户)时,我们开始看到以下错误:

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'.

使用以下堆栈:

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)

这是罪魁祸首方法:

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方法只检查db上下文是否为null,如果是,则抛出自定义异常。

emdx会话实体对象具有以下公共属性:

Guid auth_token
DateTime time_stamp
String user_id
String app_id

所以,看起来有时上面的linq会从数据库返回一些其他对象,其中第一列是int而不是guid?如果是这样 - 为什么?我是否有多个线程覆盖彼此的db上下文的问题? BTW - 我们将实例化db上下文的代码抽象为一个单独的类(BaseDB),该类也由unity处理。所以,因为服务是一个单身人士,所以每个人都有一个BaseDB实例,对吗?这是问题吗?

哦,还有一件事。我们被告知我们将拥有MSSql 2005所以在edmx文件中我们有ProviderManifestToken="2005"。但我刚检查过,我们的性能数据库服务器是2008版本。这是一个问题吗?

感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

  

我是否有多个线程覆盖彼此的db上下文的问题?

是。见这里:http://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.aspx

引用上面链接中的大黄色框:

  

ObjectContext类不是线程安全的。在多线程场景中无法确保ObjectContext中数据对象的完整性。

您可以考虑将[ThreadStaticAttribute]放在_dbContext字段上。

答案 1 :(得分:0)

我怀疑当没有结果时出现问题,并且在生成的SQL中的某处将Guid字段比较使用null值== 0。尝试将比较作为字符串(两者都是.ToString())并查看是否可以捕获导致问题的案例。