2012-05-10 6 views
14

The specified cast from a materialized 'System.Guid' type to the 'System.Int32' type is not valid.Указанные литой из материализованного типа «System.Guid» к типу «System.Int32» не является допустимым

У нас есть несколько служб WCF, которые имеют параллелизм режим Multiple и InstanceContextMode одноместный. Наша архитектура фокусируется на слабосвязанной модели, используя инъекцию зависимостей на основе конструктора. Это, в свою очередь, реализовано с использованием Unity 2.0 (web.config каждой службы имеет сопоставления между интерфейсами и типами, определенными в секции контейнера единиц). Одной из наших зависимостей является сборка DAL (уровень доступа к данным), которая использует Entity Framework 4 для связи с сервером MSSql. Классы, которые говорят с базой данных, также включены в отображение единства.

Все отлично, когда мы проводим наши интеграционные тесты. Но когда мы переходим к нашей среде производительности для запуска нагрузочных тестов (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 метод просто проверяет, является ли контекст дб равна нулю, и, если он есть, он бросает на заказ excep Тион.

emdx объект объект Session имеет следующие общие свойства:

Guid auth_token 
DateTime time_stamp 
String user_id 
String app_id 

Таким образом, это выглядит, как иногда выше LINQ возвращает какой-либо другой объект из базы данных, где первый столбец является int и не guid? И если да - почему? У меня проблема с несколькими потоками, которые переопределяют контекст db друг друга? BTW - мы абстрагировали код, который создает контекст db для отдельного класса (BaseDB), который также обрабатывается единством. Итак, поскольку служба является singleton, у меня есть один экземпляр BaseDB для всех, не так ли? Это проблема здесь?

О, еще одна вещь. Нам сказали, что у нас будет MSSql 2005, поэтому в файле edmx у нас есть ProviderManifestToken="2005". Но я только что проверил, и сервер с нашей базой данных производительности - версия 2008. Это проблема?

Благодарим за помощь.

+0

Первые простые вещи, которые я бы проверял: auth_token a Guid в вашем db? Ошибка говорит, что что-то пытается установить session.auth_token в int. Есть ли столбец идентификатора int, который неправильно отображается?Можете ли вы сделать трассировку профилей sql и определить фактический вызов sql, который был сделан? Я действительно сомневаюсь, что многопоточность вызывает проблемы. –

+0

Вы уверены, что столбец в базе данных имеет соответствующий тип свойства? Исключение говорит о том, что DbDataReader читает Guid, но свойство вашего класса - int. – Pawel

ответ

2

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

Да. Смотрите здесь: http://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.aspx

Цитата с большой желтой коробки в приведенной выше ссылке:

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

Вы можете рассмотреть вопрос о создании [ThreadStaticAttribute] на вашем _dbContext поля.

+1

Итак, основная проблема заключается в том, что ObjectContext не является Threadsafe - это нормально, но я просто хотел упомянуть, что создание свойства DbContext Threadstatic может вызвать больше проблем при использовании в WCF/Asp.Net, в зависимости от Host и того, как (или лучше, когда) вы инициализируете свойство. Например, при использовании WCF вы должны использовать OperationContext для хранения этих вещей, поскольку поток, принимающий запрос, может быть не тем же Thread, который его выполняет. см. [operationcontext] (http://msdn.microsoft.com/en-us/library/system.servicemodel.operationcontext.aspx). –

+0

@ Бернхард Кирхер: Совершенно верно - хорошая точка! – RobSiklos

0

Я подозреваю, что ваша проблема возникает, когда результатов нет, а нулевое значение == 0 используется для сравнения полей Guid где-то в сгенерированном SQL. Попробуйте выполнить сравнение как строку (.ToString() на обоих) и посмотреть, можете ли вы поймать случай, который вызывает вашу проблему.

Смежные вопросы

 Смежные вопросы