Ошибка в LINQ Left JOIN

Я написал ниже запрос в LINQ для выполнения левого соединения, но его ошибка броска:

var qry = from c in dc.category_feature_Name_trans_SelectAll_Active()
          join p in dc.product_category_feature_trans_SelectAll()
          on c.cft_id equals p.cft_id into cp
          from p in cp.DefaultIfEmpty()                      
          select new
          {
              c.cft_id,
              c.feature_id,
              c.feature_name,
              p.product_id ,
              p.value 
          };

Ошибка:

Object reference not set to an instance of an object.
Description: An unhandled exception occurred during the execution of the 
current web request. Please review the stack trace for more information about
the error and where it originated in the code.

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

Source Error:

Line 57:                       on c.cft_id equals p.cft_id into cp
Line 58:                       from p in cp.DefaultIfEmpty()                      
error Line 59:                       select new
Line 60:                       {
Line 61:                           c.cft_id,

Пожалуйста, помогите мне.

3 ответа

Решение

cp.DefaultIfEmpty() возвращает последовательность, которая будет иметь одно нулевое значение, если cp был пуст.

Это означает, что вы должны учитывать тот факт, что p в

from p in cp.DefaultIfEmpty()

может быть нулевым Теперь вы еще не сказали, что вы хотите, чтобы произошло в этом случае. Вы можете захотеть что-то вроде этого:

var qry = from c in dc.category_feature_Name_trans_SelectAll_Active()
          join p in dc.product_category_feature_trans_SelectAll()
          on c.cft_id equals p.cft_id into cp
          from p in cp.DefaultIfEmpty()                      
          select new
          {
              c.cft_id,
              c.feature_id,
              c.feature_name,
              product_id = p == null ? null : p.product_id,
              value = p == null ? null : p.value 
          };

... или вам может понадобиться другая обработка. Мы не знаем типы p.product_id или же p.valueчто не помогает (Например, вам нужно немного больше поработать с приведенным выше кодом, если product_id это тип значения.)

Вы делаете левое соединение, так p может быть null, Вы должны учитывать это.

Вот запрос, который должен работать, хотя я не знаю точно, что это за значение p.value, Запрос будет работать, если значение является ссылочным типом. Если значение является типом значения, то используйте приведение типа product_id бросать.

var qry = from c in dc.category_feature_Name_trans_SelectAll_Active()
            join p in dc.product_category_feature_trans_SelectAll()
            on c.cft_id equals p.cft_id into cp
            from p in cp.DefaultIfEmpty()
            select new
            {
                c.cft_id,
                c.feature_id,
                c.feature_name,
                product_id = p == null ? (int?)null : p.product_id,
                value = p == null ? null : p.value,
            };

Я столкнулся с той же проблемой при использовании LEFT JOIN для нескольких таблиц в запросе LINQ, и я столкнулся с исключением нулевой ссылки. Я использовал трюк, чтобы проверить нулевое значение, используя "?" Пожалуйста, поправьте меня, если мой подход неверен.

var deviceResultDetails = from pa in programAliasrecords
                          join pgm in Newprogramrecords on pa.program_id equals pgm.id into pgm_join
                          from pgm2 in pgm_join.DefaultIfEmpty()
                          join latest_fw in firmwareWithIdrecords on pgm2?.latest_firmware_id equals latest_fw?.id into latest_fw_join
                          from latest_fw2 in latest_fw_join.DefaultIfEmpty()
                          join dev_fw in firmwareWithIdrecords on pgm2?.firmware_group_id equals dev_fw?.firmware_group_id into dev_fw_join
                          from dev_fw2 in dev_fw_join.DefaultIfEmpty()
                          join vv in vulnerabilityrecords on pgm2?.id equals vv?.program_id into vv_join
                          from vv2 in vv_join.DefaultIfEmpty()
                          where 
                          dev_fw2?.version == row.firmware    
                          && pa?.keyword == row.model      

                             select new _deviceResults
                             {
                                 model = row.model, 
                                 serial = row.serial, 
                                 firmware = row.firmware, 
                                 firmware_date = dev_fw2.br_date == null ? null: dev_fw2.br_date,
                                 latest_firmware = latest_fw2.version == null ? null : latest_fw2.version,
                                 latest_firmware_date = latest_fw2.br_date == null ? null : latest_fw2.br_date,

                                 status = Convert.ToInt32(vulnerability_count) > 0 && pgm2.out_of_support == "TRUE" ? "Vulnerable (End of Suport)" :
                                          Convert.ToInt32(vulnerability_count) > 0 && pgm2.out_of_support == " " ? "Vulnerable (Upgradeable)" :
                                                 pgm2.out_of_support == "TRUE" ? "Out-of-support" :
                                                 Convert.ToInt32(dev_fw2.revs_out_of_date) > 1 ? "Out-of-date" :
                                                 pgm2.id == "NonHP" ? "NonHP" :
                                                 pgm2.id == "NoFirmware" ? "No Firmware" :
                                                 pgm2.id == "HPink" || pgm2?.id == "HPOther" ? "Not evaluated (model not included yet)" :
                                                 pgm2.id == " " ? "Not evaluated (model not recognized)" :
                                                 dev_fw2.version == " " ? "Not evaluated (firmware version missing)" :
                                                 dev_fw2.id == " " ? "Not evaluated (firmware version mismatch)" :    // && dev_fw.id  in (select version from firmware) 
                                                 dev_fw2.id == " " ? "Not evaluated (firmware version unrecognized)" :
                                                 dev_fw2.br_date == " " || pgm2.id == " " || dev_fw2.revs_out_of_date == " " ? "Not evaluated" : "OK",

                                 out_of_support = pgm2.out_of_support == "" ? "false" : pgm2.out_of_support,
                                 revs_out_of_date = dev_fw2.revs_out_of_date == null ? null : dev_fw2.revs_out_of_date,
                                 program_id = pgm2.id == null ? null :  pgm2.id,
                                 firmware_id = dev_fw2.id == null ? null : latest_fw2.br_date
                             };

Используйте ваш класс модели в качестве параметра для функции DefaultIfEmpty().

from p in cp.DefaultIfEmpty(new yourModelClass())
Другие вопросы по тегам