2014-11-21 2 views
0

Нижеприведенный запрос состоит из нескольких статей INNER JOIN.Должна ли ссылка на исключение исключения пустой переменной

В таблице Student есть много внешних ключей, которые заменяются именами в запросе. Я использую LEFT OUTER JOIN запрос ниже. Обратите внимание, что MarkID в Students может быть null. Это означает, что marksGroup.DefaultifEmpty() может вернуться null. Поэтому, если я помещаю только m вместо m != null ? m.MarkName : "-- Not marked --" в последней строке, код IMO должен генерировать исключение, когда m имеет значение null, потому что я имею в виду эту переменную, но это не так. На примере, на котором я строю этот запрос, возникает исключение для компилятора. См. Код:

var result = from st in dbContext.Students where st.DepartmentID == 17 
      join d in dbContext.Departments on st.DepartmentID equals d.DepartmentID 
      join sv in dbContext.SoftwareVersions on st.SoftwareVersionID equals sv.SoftwareVersionID 
      join stat in dbContext.Statuses on st.StatusID equals stat.StatusID 
      join m in dbContext.Marks on st.MarkID equals m.MarkID into marksGroup 
      from m in marksGroup.DefaultIfEmpty() 
      select new 
      { 
       student = st.StudentName, 
       department = p.DepartmentName, 
       software = sv.SoftwareVersionName, 
       status = st.StatusName, 
       marked = m != null ? m.MarkName : "-- Not marked --" 
      }; 

Что мне не хватает. Я все еще новичок в терминах C# и LINQ.

+1

'[...], если я ставлю только m [...]'. Ссылка на объект не вызовет исключения. Однако, выполняя любую операцию на нем, ** будет бросать один **. То есть, пытается вызвать метод или свойство. Например, 'отмеченное = m' не должно вызывать никаких исключений, вы просто ссылаетесь на объект. 'mark = m.MarkName', однако, должен вызывать ** NullReferenceException **, если' m == null'. –

+0

Вы хотите сказать, что 'отмеченный = m' должен вызывать исключение? –

+0

@MatiCicero Спасибо Мати. Это объясняет разницу между мной и примером. Я снова посмотрел на примерный код, и автор действительно попытался ссылаться на свойство нулевого объекта :) Cheers! – Celdor

ответ

1

Когда вы выполняете инструкцию LINQ для SQL-сервера (я предполагаю, что у вас есть Entity Framework здесь), операционная команда преобразуется в SQL и выполняется механизмом базы данных.

Так что это то, что делает среда .Net:

  • Перевести заявление (которое является Expression) в SQL
  • Послать SQL в базу данных с помощью ADO.NET.
  • Получите набор результатов SQL (по существу массив строк, где строка сама по себе является массивом значений).
  • Создайте объекты из этих строк.

В вашем случае, объекты, которые будут созданы безопасно могут быть определены в части

select new 
{ 
    student = st.StudentName, 
    department = p.DepartmentName, 
    software = sv.SoftwareVersionName, 
    status = st.StatusName, 
    marked = m.MarkName 
} 

Единственное, что во время выполнения .Net касается является создание экземпляра анонимного типа и установить его свойства из одной строки в результирующем наборе. В некоторых строках значение для marked может быть null, поэтому marked установит значение null в этом конкретном объекте. В среде .NET не существует объекта MarksGroup.

Конечно, в LINQ к объектам это было бы совершенно иначе. Там нулевая проверка абсолютно необходима для предотвращения ссылок на нулевые объекты.

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