2016-07-26 1 views
2

Допустим, у меня есть этот код:Во время отладки, могу ли я просматривать объект, вызывающий исключение в LINQ?

IDictionary<int, int> itemPriceDict = loadItemPriceDictionary(); 
IList<IRow> dbItems = loadItemsFromDatabase(); 

IList<ItemDTO> itemDTOs = dbItems 
    .Select(dbItem => new ItemDTO() 
    { 
     Id = dbItem.Id, 
     Label = dbItem.Label, 
     PriceTag = itemPriceDict[dbItem.Id] // Possible KeyNotFoundException 
    }) 
    .ToList(); 

и иногда я получаю исключение KeyNotFound, когда данная цена тега не существует для данного dbItem.

Теперь при отладке в Visual Studio и исключение, вы можете увидеть StackTrace, TargetSite, которые показывают вам, что строка кода срабатывает, но это можно выяснить, какой объект (dbItem) вызвал исключение и отображать его данные в отладчике? Например, в окне просмотра?

Я хотел бы:

  1. Либо знать, какой ключ не присутствовал в словаре
  2. Или еще лучше знать ключ, а также на dbItem обработанную в Select

Но без необходимости добавлять или изменять какой-либо код.

P.S .: Я знаю, что могу переписать код как цикл, но я бы этого не хотел.

ответ

0

Оказывается, это прекрасно, чтобы проверить такой объект. Вот демонстрационный код в действии:

Inspecting variable in LINQ while exception is thrown

Кроме того, в Visual Studio 2015 можно оформить лямбда-выражения непосредственно в окне Watch для запроса коллекции перед запуском линии, которая бросает исключение.

enter image description here

0

Попробуйте добавить еще Постулаты:

IList<ItemDTO> itemDTOs = dbItems.Where(dbitem => dbitem.itemPriceDict[dbItem.Id] != null) 
    .Select(dbItem => new ItemDTO() 
    { 
     Id = dbItem.Id, 
     Label = dbItem.Label, 
     PriceTag = itemPriceDict[dbItem.Id] // Possible KeyNotFoundException 
    }) 
    .ToList(); 
+2

Это не сработает. Вы получили бы предложение KeyNotFoundException в Where, потому что словарь не возвращает null, если ключ отсутствует. –

+0

ok попробуйте этот путь: Где (dbitem => dbitem.itemPriceDict [dbItem.Id] .Any()) – MKasprzyk

+0

К сожалению, вы также получите исключение KeyNotFound. Это происходит в dbitem.itemPriceDict [dbItem.Id] перед вызовом Any(). Вы имеете в виду это: Where (dbItem => itemPriceDict.ContainsKey (dbItem.Id)) Но я не хочу изменять какой-либо код. Я бы посмотрел его в режиме отладчика - например, «Смотри окно». –

4

Вы можете написать свой Select как таковой:

.Select(dbItem => 
    { 
     return new ItemDTO() 
     { 
      Id = dbItem.Id, 
      Label = dbItem.Label, 
      PriceTag = itemPriceDict[dbItem.Id] // Possible KeyNotFoundException 
     }) 
    } 
    .ToList(); 

Это позволит вам разместить точки останова внутри отдельных оценок.

Еще лучше, зайдите в меню «Отладка», затем выберите «Исключения» (он находится под подменю Windows в моей Visual Studio Edition).

Затем настройте его так, чтобы он разбился либо на KeyNotFoundException, либо за исключением вашего выбора.

отладчик будет автоматически ломается, когда происходит исключение позволяет проверить состояние соответствующих объектов

2

для целей отладки вы можете сделать это:

IList<ItemDTO> itemDTOs = dbItems 
      .Select(dbItem => { 
       try 
       { 
        var value = itemPriceDict[dbItem.Id]; 
       } 
       catch (KeyNotFoundException) 
       {//Breakpoint goes here 
       } 
       // Possible KeyNotFoundException 
       new ItemDTO() 
       { 
        Id = dbItem.Id, 
        Label = dbItem.Label, 
        PriceTag = itemPriceDict[dbItem.Id] // Possible KeyNotFoundException 
       }; 
      }) 
      .ToList(); 

или непосредственно получить список, это:

var missingKeys = dbitems.Where(dbItem => !itemPriceDict.ContainsKey(dbItem.Id)).ToList(); 
+0

Это хорошо работает для целей отладки. Но вы должны переписать код. Я хотел бы осмотреть объект в окне просмотра или где-то без изменения существующего кода. –

+0

Ваши варианты очень ограничены, если вы не хотите менять свой код ... Насколько я могу судить, если вы хотите, чтобы ваш код оставался неизменным, единственным вариантом является установка контрольной точки внутри выражения LAMBA (новой части ItemDTO), затем остановите и проверьте каждый идентификатор в словаре вручную. Программирование - динамичная профессия, вы должны изменить свой код, если хотите получить правильные результаты. – MichaelThePotato

+0

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

0

Когда нет ключа в словаре, вы получите исключение KeyNotFoundException. Держите верхнюю переменную и назначьте ключ каждый раз, когда вы введете запрос Linq. Вы можете украсить свой код с помощью try и catch block.

(KeyNotFoundException экс)

try 
    { 
     int key; 

     Dictionary<int, int> dict = new Dictionary<int, int>() 
     { 
      {1, 2}, 
      {2,3} 
     }; 

     var x = (from y in dict 
       select new 
       { 
        value = dict[4] 

       }).ToList(); 

    } 
    catch (KeyNotFoundException ex) 
    { 
     //key that is not there 
    } 
    catch (Exception ex) 
    { 

    } 
2

[отказ от ответственности: Я работаю в OzCode]

Вы пробовали OzCode. Поддержка отладки Linq была добавлена ​​в EAP, и одна из особенностей заключается в том, что она может предсказать, будет ли запрос выдавать исключение и отображать оскорбительный элемент.

enter image description here

Таким образом, вам не нужно вскрывать код или попробовать и отладить его в голове.

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