2008-09-17 2 views
21

У меня очень трудная попытка отладить LINQ to SQL и внести изменения.Отладка LINQ to SQL SubmitChanges()

Я использовал http://weblogs.asp.net/scottgu/archive/2007/07/31/linq-to-sql-debug-visualizer.aspx, который отлично подходит для отладки простых запросов.

Я работаю в DataContext класс для моего проекта со следующим фрагментом из моего приложения:

JobMaster newJobToCreate = new JobMaster(); 
newJobToCreate.JobID = 9999 
newJobToCreate.ProjectID = "New Project"; 
this.UpdateJobMaster(newJobToCreate); 
this.SubmitChanges(); 

Я наловить очень странные исключения, когда я бегу this.SubmitChanges;

Index was outside the bounds of the array. 

Трассировка стека идет места я не могу ступить в:

at System.Data.Linq.IdentityManager.StandardIdentityManager.MultiKeyManager`3.TryCreateKeyFromValues(Object[] values, MultiKey`2& k) 
    at System.Data.Linq.IdentityManager.StandardIdentityManager.IdentityCache`2.Find(Object[] keyValues) 
    at System.Data.Linq.IdentityManager.StandardIdentityManager.Find(MetaType type, Object[] keyValues) 
    at System.Data.Linq.CommonDataServices.GetCachedObject(MetaType type, Object[] keyValues) 
    at System.Data.Linq.ChangeProcessor.GetOtherItem(MetaAssociation assoc, Object instance) 
    at System.Data.Linq.ChangeProcessor.BuildEdgeMaps() 
    at System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode) 
    at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode) 
    at System.Data.Linq.DataContext.SubmitChanges() 
    at JobTrakDataContext.CreateNewJob(NewJob job, String userName) in D:\JobTrakDataContext.cs:line 1119 

Кто-нибудь есть какие-либо инструменты или методы, которые они используют? Я что-то пропустил?

EDIT: Я отладки .net настройки с предложением выключателем, однако код .net 3.5 пока нет в наличии: http://referencesource.microsoft.com/netframework.aspx

EDIT2: Я изменил к InsertOnSubmit согласно sirrocco годов предложение, все еще получающее ту же ошибку.

EDIT3: Я реализовал предложения Сэма пытается войти в SQL сгенерированного и поймать ChangeExceptoinException. Эти предложения не пролить больше света, я никогда не получаю, чтобы генерировать SQL, когда мое исключение бросается.

EDIT4: Я нашел ответ, который работает для меня ниже. Это просто теория, но она исправила мою текущую проблему.

+0

Эта ошибка произошла с множеством клиентов, только на компьютерах с Windows XP, я нашел это исправление, которое решило проблему. [I386] (http://hotfixv4.microsoft.com/.NET%20Framework%203.5%20-%20Windows%20Server%202003,%20WindowsXP,%20Windows%20Vista,%20Windows%20Server%202008%20 (MSI)/sp1/DevDiv975687/30729.5821/бесплатно/448814_intl_i386_zip.exe) и [x64] (http://support.microsoft.com/hotfix/KBHotfix.aspx?kbnum=963657&kbln=en-us) – gpiccin 2013-05-25 21:12:40

ответ

8

Во-первых, спасибо всем за помощь, я наконец нашел его.

Решение заключалось в том, чтобы удалить .dbml-файл из проекта, добавить пустой .dbml-файл и повторно заполнить его таблицами, необходимыми для моего проекта, из «Server Explorer».

Я заметил несколько вещей, в то время как я делал это:

  • Есть несколько столов в системе именованных двух слов и пробел между словами, то есть «Работа Master». Когда я вернул этот стол в файл .dbml, он создаст таблицу с именем «Job_Master», она заменит пространство символом подчеркивания.
  • В оригинальном файле .dbml один из моих разработчиков прошел через .dbml-файл и удалил все подчеркивания, поэтому «Job_Master» станет «JobMaster» в файле .dbml. В коде мы могли бы ссылаться на таблицу в более стандартном соглашении об именах для нас.
  • Моя теория в том, что где-то перевод с «JobMaster» на «Job Master» был потерян при выполнении проекции, и я продолжал сталкиваться с ошибкой массива за пределами границ.

Это только теория. Если кто-то может лучше объяснить это, я хотел бы получить конкретный ответ здесь.

1

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

Это конечно только помогает, как только вы получите мимо исключений ...

0

Хмм.

Принимая WAG (Wild Ass Guess), мне кажется, что LINQ-SQL пытается найти объект с id, который не существует, так или иначе основанный на создании класса JobMaster. Существуют ли внешние ключи, связанные с этой таблицей, так что LINQ to SQL попытается извлечь экземпляр класса, который может не существовать? Кажется, вы устанавливаете ProjectID нового объекта в строку - действительно ли у вас есть идентификатор, который является строкой? Если вы пытаетесь установить его в новый проект, вам нужно будет создать новый проект и получить его идентификатор.

И наконец, что делает UpdateJobMaster? Может ли это быть что-то такое, что применимо выше?

1

VS 2008 имеет возможность отладки, хотя.NET Framework (http://blogs.msdn.com/sburke/archive/2008/01/16/configuring-visual-studio-to-debug-net-framework-source-code.aspx)

Это, вероятно, ваш лучший выбор, вы можете увидеть, что происходит, и то, что все свойства в точный момент времени

+0

На сегодняшний день http: // sourcesource .microsoft.com/netframework.aspx исходный код для .net 3.5 пока недоступен. – ben 2008-09-18 14:28:38

2

Ошибка вы имеете в виду выше, как правило, вызвано ассоциации, указывающие в неправильном направлении. Это происходит очень легко, когда вручную добавляются ассоциации к дизайнеру, поскольку стрелки объединения в дизайнере L2S обращаются назад по сравнению с инструментами моделирования данных.

Было бы неплохо, если бы они бросили более описательное исключение, и, возможно, они будут в будущей версии. (Damien/Matt ...?)

1

Почему вы делаете UpdateJobMaster в новом экземпляре? Разве это не будет InsertOnSubmit?

JobMaster newJobToCreate = new JobMaster(); 
newJobToCreate.JobID = 9999 
newJobToCreate.ProjectID = "New Project"; 
this.InsertOnSubmit(newJobToCreate); 
this.SubmitChanges(); 
+0

Я изменил на InsertOnSubmit, все еще получая ту же ошибку – ben 2008-09-18 14:55:50

4

Вы можете создать частичный класс для DataContext и использовать Созданный или то, что вы частичный метод для настройки журнала в console.out завернутого в #if DEBUG .. это поможет вам увидеть запросы, выполняемые при отладке любого экземпляра используемого вами файла данных.

я нашел полезным во время отладки LINQ к SQL исключений ..

partial void OnCreated() 
{ 
#if DEBUG 
     this.Log = Console.Out; 
#endif 
} 
6

Моя первая отладка действий будет смотреть на сгенерированного SQL:

JobMaster newJobToCreate = new JobMaster(); 
newJobToCreate.JobID = 9999 
newJobToCreate.ProjectID = "New Project"; 
this.UpdateJobMaster(newJobToCreate); 
this.Log = Console.Out; // prints the SQL to the debug console 
this.SubmitChanges(); 

Второй будет захватить исключение ChangeConflictException и посмотреть подробности сбоя.

catch (ChangeConflictException e) 
    { 
    Console.WriteLine("Optimistic concurrency error."); 
    Console.WriteLine(e.Message); 
    Console.ReadLine(); 
    foreach (ObjectChangeConflict occ in db.ChangeConflicts) 
    { 
     MetaTable metatable = db.Mapping.GetTable(occ.Object.GetType()); 
     Customer entityInConflict = (Customer)occ.Object; 
     Console.WriteLine("Table name: {0}", metatable.TableName); 
     Console.Write("Customer ID: "); 
     Console.WriteLine(entityInConflict.CustomerID); 
     foreach (MemberChangeConflict mcc in occ.MemberConflicts) 
     { 
     object currVal = mcc.CurrentValue; 
     object origVal = mcc.OriginalValue; 
     object databaseVal = mcc.DatabaseValue; 
     MemberInfo mi = mcc.Member; 
     Console.WriteLine("Member: {0}", mi.Name); 
     Console.WriteLine("current value: {0}", currVal); 
     Console.WriteLine("original value: {0}", origVal); 
     Console.WriteLine("database value: {0}", databaseVal); 
     } 
    } 
    } 
+0

Мое приложение никогда не генерирует SQL, и оно не генерирует никаких изменений в ChangeConflictExceptions, оно взрывается до этого шага. – ben 2008-09-19 14:10:39

+3

Ницца. Для парней, использующих ASP.Net, просто замените консоль. через Debug. для получения результата в окне вывода – citronas 2012-01-05 14:16:43

0

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

Это, наряду с другими ограничениями, заставило нас отказаться от конструктора и разработать классы вручную. После того, как мы привыкли к шаблонам, на самом деле это проще, чем использование дизайнера.

0

Сегодня я разместил аналогичный вопрос сегодня: Strange LINQ Exception (Index out of bounds).

Это другой вариант использования - где эта ошибка происходит во время SubmitChanges(), моя происходит во время простого запроса, но это также ошибка индекса вне диапазона.

кросс проводки в этом вопросе в случае сочетания данных в вопросах помогает хороший самаритянина ответ либо :)

0

Убедитесь, что все «первичный ключ» столбцы в DBML на самом деле относятся к первичным клавиш на таблицы базы данных. У меня была ситуация, когда дизайнер решил разместить дополнительный столбец PK в dbml, а это означало, что LINQ to SQL не смог найти обе стороны внешнего ключа при сохранении.

0

Я недавно столкнулся с таким же вопросом: что я сделал

Proce proces = unit.Proces.Single(u => u.ProcesTypeId == (from pt in context.ProcesTypes 
                     where pt.Name == "Fix-O" 
                     select pt).Single().ProcesTypeId && 
                     u.UnitId == UnitId); 

Вместо:

Proce proces = context.Proces.Single(u => u.ProcesTypeId == (from pt in context.ProcesTypes 
                    where pt.Name == "Fix-O" 
                    select pt).Single().ProcesTypeId && 
                    u.UnitId == UnitId); 

Где контекст явно объект DataContext и «единица» экземпляр объекта модульного, Класс данных из файла dbml.

Далее я использовал объект «proce», чтобы установить свойство в экземпляре другого объекта класса данных. Вероятно, механизм LINQ не смог проверить, было ли свойство, которое я устанавливал из объекта «proce», было разрешено в команде INSERT, которая должна была быть создана LINQ, чтобы добавить другой объект класса данных в базу данных.

30

Мне всегда было полезно узнать, какие изменения отправляются в DataContext в методе SubmitChanges().

Я использую метод DataContext.GetChangeSet(), он возвращает экземпляр объекта ChangeSet, который содержит 3 объекта IList только для чтения, которые либо были добавлены, изменены или удалены.

Вы можете разместить точку останова непосредственно перед вызовом метода SubmitChanges и добавьте часы (или Quick Watch), содержащий:

ctx.GetChangeSet(); 

Где CTX является текущим экземпляром вашей DataContext, а затем вы будете способный отслеживать все изменения, которые будут эффективны при вызове SubmitChanges.

0

У меня была такая же непонятная ошибка.

У меня было отношение внешнего ключа к столбцу таблицы, который не был основным ключом таблицы, а уникальным столбцом. Когда я изменил уникальный столбец в качестве первичного ключа таблицы, проблема исчезла.

Надеюсь, это поможет любому!

0

Опубликован мой опыт с этим исключением в ответ на SO # 237415

1

Это почти наверняка не будет каждая первопричина, но я столкнулся с этим точно таким же исключением в моем проекте - и обнаружил, что основная причина было что во время построения класса сущности было выбрано исключение. Как ни странно, истинное исключение «потеряно» и вместо этого проявляется как исключение ArgumentOutOfRange, возникающее на итераторе оператора Linq, которое извлекает объект/s.

Если вы получаете эту ошибку, и вы вводили методы OnCreated или OnLoaded в своих POCOs, попробуйте выполнить эти методы.

2

Это то, что я сделал

... 
var builder = new StringBuilder(); 
try 
{ 
    context.Log = new StringWriter(builder); 
    context.MY_TABLE.InsertAllOnSubmit(someData); 
    context.SubmitChanges();     
} 
finally 
{ 
    Log.InfoFormat("Some meaningful message here... ={0}", builder); 
} 
0

я оказался на этот вопрос при попытке отлаживать LINQ ChangeConflictException. В конце концов я понял, что проблема заключалась в том, что я вручную добавил свойство таблицы в моем файле DBML, но я забыл установить свойство, как Nullable (должно быть верны в моем случае) и данных сервера Тип

Надеюсь, это поможет кому-то.

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