2012-01-03 7 views
0

Это несколько сложно понять, я думаю, возможно, я чего-то не хватает. Я новичок, пытающийся установить базу данных, сопоставленную с Linq-to-SQL на моем сервере. Существует функция вызывается клиентами, который извлекает UserAccount из базы данных:Linq to SQL InvalidCastException

public static explicit operator Dictionary<byte, object>(UserAccount a) 
    { 
     Dictionary<byte, object> d = new Dictionary<byte, object>(); 
     d.Add(0, a.AuthenticationDatas.Username); 
     int charCount = a.Characters.Count; 
     for (int i = 0; i < charCount; i++) 
     { 
      d.Add((byte)(i + 1), (Dictionary<byte, object>)a.Characters[i]); 
     } 
     return d; 
    } 

Что это на самом деле делает это преобразование типа UserAccount на мой сервер типа данных словаря. Сам UserAccount извлекается из базы данных, а затем преобразуется через эту функцию.

Однако, когда я запускаю эту функцию, я получаю InvalidCastException на линии:

int charCount = a.Characters.Count;

Кроме того, когда VS точки останова @ этой линии, я могу подождать несколько секунд и продолжить и excpetion пропадут! После этого он извлекает Characters.Count.

Вот мои Характеры отображение:

[global::System.Data.Linq.Mapping.AssociationAttribute(Name="UserAccount_Character", Storage="_CharactersTBs", ThisKey="UID", OtherKey="UID")] 
    public EntitySet<Character> Characters 
    { 
     get 
     { 
      return this._Characters; 
     } 
     set 
     { 
      this._Characters.Assign(value); 
     } 
    } 

Я верю Что происходит в том, что запрос каким-то образом выполняются в другом потоке, чем тот, который взаимодействует с базой данных, и это ошибка, прежде чем база данных на самом деле может получить таблицу символов. Я не совсем уверен ...

Кто-нибудь знает, в чем проблема, и как я могу ее синхронизировать (не добавляя задержку gimp)?

EDIT:

Хорошо я сузил проблему. Это не имеет никакого отношения к различным сетям нитей, а что нет ... Просто я просто глуп. Вот простой запрос базы данных, который вызывает InvalidCastException @ line int count = UA.Characters.Count;

static void Main(string[] args) 
    {   

     IEnumerable<UserAccount> query = from p in PBZGdb.Instance.AuthenticationDatas 
             where p.Username == "Misha" && p.Password == "123" 
             select p.UserAccount; 
     UserAccount UA = query.ElementAt(0); 
     int count = UA.Characters.Count; 
     Console.WriteLine(count); 
     Console.ReadKey(); 
    } 

(постскриптум) UA не равно нулю, что действительно находит правильный экземпляр UserAccount и имеет 2 символов. Если я подожду несколько секунд и повторю попытку, исключение исчезнет. Что я делаю неправильно? Это первый раз, когда я действительно использую базу данных в VS, пожалуйста, помогите! :)

+0

Укажите точное сообщение об исключении. – leppie

+0

Странно, я подозреваю, что '(byte) (i + 1)' может генерировать исключение. –

+0

Вы уверены, что это в этой строке 'int charCount = a.Characters.Count;'? Запустили ли вы его в режиме отладки или выпуска? Из-за оптимизаций, которые происходят в режиме выпуска, отладчик иногда может немного запутаться. – ChrisWue

ответ

1

Эй просто хочу, чтобы кто с той же проблемой знаю, я понял это. Что случилось, я был вручную переименован в файл LINQ .dbml, когда я добавил его в свой проект после того, как он был создан с помощью sqlmetal. И, конечно же, я сделал это непоследовательно (он был переименован в конструктор, но не в файл .cs). Я только что повторно создал новый .dbml-файл с sqlmetal с правильным именем на этот раз, и все работает как масло!

Спасибо, ребята!

1

Похоже, вы столкнулись с проблемой с отложенным выполнением EntitySet. Простой способ проверить это и потенциально обойти его - попытаться вызвать метод .Count() вместо того, чтобы обращаться к свойству .Count.

Вы можете посмотреть в отладчике, как только вы нажмете эту строку, и посмотрите также на значение a.Characters.IsDeferred.


редактировать

Другая вещь, которую вы могли бы попробовать было бы заставить выполнение запроса, неявного вызова это .GetEnumerator() (и связанных с ними .MoveNext()), заменив свой цикл с foreach:

int i = 0; 
foreach (var character in a.Characters) 
{ 
    d.Add(/* ... */); 
    ++i; 
} 

double edit

удалены комментарии о

d.Add((byte)(i + 1), (Dictionary<byte, object>)a.Characters[i]); 

после осветления в комментариях ниже

+0

Я также проверил IsDeferred, он говорит правду. Но я не слишком уверен, что это означает? –

+0

Если '.IsDeferred' истинно, то запрос еще не выполнен (или закончен). Кроме того, уверены ли вы, что вы можете использовать тип 'Character' для ввода словаря '? Это то, что, похоже, происходит в строке 8 вашего первого блока кода: 'd.Add ((byte) (i + 1), (Dictionary ) a.Characters [i]);'. Это устанавливает 'object' в' '' '' '' Словарь 'to _another_' Dictionary '. Это действительно то, что вы намеревались? – rejj

+0

Я пробовал использовать .Count() Я получаю то же самое исключение «Указанный приказ недействителен». Если я подожду несколько секунд, то нажмите «Возобновить», он работает нормально ... Я думаю, что он не приостанавливает поток, который запрашивает его. –