Ошибка в 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())