Linq Left Outer Join - ошибка DefaultIfEmpty - PullRequest
6 голосов
/ 13 января 2011

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

Этот запрос не включает устройства, которые не имеют параметров устройства. Если я добавлю .DefaultIfEmpty (), как показано ниже, я получу эту ошибку:

"Ошибка приведения к типу значения 'Int64', так как материализованное значение является нулевым. Либо универсальный параметр типа результата, либо запрос должен использовать тип, допускающий значение NULL." Какой правильный синтаксис для DefaultIfEmpty?

            var Devices = from d in dc.DeviceTypes
                      join p in dc.DeviceParameters on d.TypeID equals p.TypeID into tmpTable
                      from items in tmpTable.DefaultIfEmpty()
                      group items by d.DeviceName into g
                      select new
                      {
                          DeviceName = g.Key,
                          settings = from s in g
                                     select new
                                     {
                                         ParamName = s.ParamName,
                                         Param1 = s.Param1,
                                         Param2 = s.Param2,
                                         Param3 = s.Param3
                                     }
                      };

Ответы [ 2 ]

4 голосов
/ 13 января 2011

Если вы определили отношение внешнего ключа, я думаю, что решение довольно простое, если я что-то упустил:

var Devices = dc.DeviceTypes
    .Select(p=>new 
        {
             DeviceName = p.DeviceName ,
             settings = p.DeviceParameters
                 .Select(q=>new
                 {
                     ParamName = p.ParamName,
                     Param1 = q.Param1,
                     Param2 = q.Param2,
                     Param3 = q.Param3
                 })
        });

В любом случае, я бы, вероятно, сделал бы часть настроек следующим образом:

settings = p.DeviceParameters.ToList()
1 голос
/ 13 января 2011

Я считаю, что проблема, с которой вы сталкиваетесь в своем запросе, заключается в том, что с помощью вызова DefaultIfEmpty() вы пытаетесь извлечь значения из нулевого объекта. Если у вас есть действительный DeviceType, но у вас нет сопоставленных DeviceParameters, тогда, когда он пытается материализовать свойство settings с помощью этого оператора:

settings = from s in g
select new
{
    ParamName = s.ParamName,
    Param1 = s.Param1,
    Param2 = s.Param2,
    Param3 = s.Param3
}

Он пытается создать новый объект, и объект для "s" является нулевым, поэтому попытка получить доступ к свойству ParamName или Param1 и т. Д. Не будет работать. Я попробовал тот же код в LINQPad, и когда я удалил вызов DefaultIfEmpty (), то все заработало.

Не зная свойств и их типов, я не могу быть уверен, но, как я уже сказал, основываясь на реализации аналогичного кода в LINQPad, я получил аналогичные результаты.

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