2010-12-21 2 views
3

Я пытаюсь преобразовать SQL-запрос в запрос LINQ к объектам, но у меня возникли некоторые проблемы с LINQ , выберите.LINQ to Entities - множественные соединения - исключение ссылочной ссылки в 'Select'

Вот SQL-запрос, который выполняет, как ожидалось:

SELECT distinct(p.PendingID, 
     p.Description, 
     p.Date, 
     f.Status, 
     u.UserName, 
     m.MapID 
    FROM Pending p 
    JOIN Users u 
    ON p.UserID = u.UserID 
    LEFT JOIN Forks f 
    ON p.PendingID = f.PendingID 
    LEFT JOIN Maps m 
     ON f.ForkID = m.ForkID 
    ORDER BY p.Date DESC 

Вот в LINQ для сущностей запроса, как он у меня до сих пор:

var pList = (from pending in pendingItems 
// JOIN 
from user in userList.Where(u => pending.UserID == u.UserID) 
// LEFT OUTER JOIN 
from fork in forkList.Where(f => pending.ID == f.PendingID) 
.DefaultIfEmpty() 
// LEFT OUTER JOIN 
from map in mapList.Where(m => fork.ID == m.ForkID) 
.DefaultIfEmpty() 
orderby pending.Date descending 
select new 
{ 
ItemID = pending.ID,     // Guid 
Description = pending.Description, // String 
Date = pending.Date,     // DateTime 
Status = fork.Status,    // Int32 (*ERROR HERE*) 
UserName = user.UserName,   // String 
MapID = map.ID      // Guid (*ERROR HERE*) 
}) 
.Distinct() 
.ToList(); 

Запрос LINQ не будет работать на любой из после двух строк, которые пытаются присвоить значения, полученные из , влево на внешнем соединении. Если следующие строки опущены, запрос LINQ завершается без ошибок:

Status = fork.Status, 
MapID = map.ID 

Почему эти два назначение собственности неудовлетворительного в блоке выбора в запросе LINQ в?

+0

Вы действительно используете это против EF или факсимильной связи в вашей базе данных? Во-вторых, это код в LINQPad и вы можете проверить сгенерированный SQL (если против EF)? –

+0

Я думаю, что это ошибка компилятора, поэтому он может видеть ошибки на обеих линиях. – tster

+1

tster: Заголовок сообщения говорит «Null Reference Exception», поэтому я сомневаюсь, что это ошибка компилятора. – Gabe

ответ

1

Проблема в том, что из-за ваших внешних соединений fork и map может быть пустым. Конечно, когда они равны нулю, вы не можете получить доступ к их свойствам. Вам может понадобиться что-то вроде этого:

Status = (fork == null) ? null : fork.Status, 
MapID = (map == null) ? null : map.ID 
+0

Они не могут быть нулевыми, потому что DefaultIfEmpty возвращает коллекцию, а если их нет, она возвращает одноэлементную коллекцию. Однако значение в коллекции может быть нулевым. – tster

+0

tster: переменные 'map' и' fork' перебирают значения, возвращаемые 'DefaultIfEmpty', поэтому они действительно могут быть нулевыми. – Gabe

+0

О, стреляй, я привык смотреть на 'let x = ...' вместо нескольких из предложений. – tster

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