Отладка LINQ to SQL SubmitChanges () - PullRequest
       99

Отладка LINQ to SQL SubmitChanges ()

21 голосов
/ 17 сентября 2008

Мне очень трудно пытаться отлаживать LINQ to SQL и отправлять изменения.

Я использовал 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();

Я поймаю некоторые очень странные исключения при запуске этого. 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 по предложению Slace, однако код .net 3.5 пока недоступен: http://referencesource.microsoft.com/netframework.aspx

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

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

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

Ответы [ 19 ]

31 голосов
/ 02 апреля 2009

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

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

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

ctx.GetChangeSet();

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

8 голосов
/ 19 сентября 2008

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

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

Я заметил пару вещей, пока делал это:

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

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

6 голосов
/ 18 сентября 2008

Моим первым действием отладки было бы посмотреть на сгенерированный 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);
      }
    }
  }
4 голосов
/ 18 сентября 2008

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

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

partial void OnCreated()
{
#if DEBUG
      this.Log = Console.Out;
#endif
}
2 голосов
/ 18 сентября 2008

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

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

2 голосов
/ 17 июля 2012

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

...
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);
}
1 голос
/ 18 сентября 2008

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

JobMaster newJobToCreate = new JobMaster();
newJobToCreate.JobID = 9999
newJobToCreate.ProjectID = "New Project";
this.InsertOnSubmit(newJobToCreate);
this.SubmitChanges();
1 голос
/ 18 сентября 2008

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

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

1 голос
/ 17 сентября 2008

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

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

1 голос
/ 04 августа 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...