LINQ左连接出错

12

我在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,

请帮帮我。

4个回答

16
cp.DefaultIfEmpty()返回一个序列,如果cp为空,则该序列将包含一个空值。
这意味着您必须考虑到中括号内的p可能是空的情况。
from p in cp.DefaultIfEmpty()

可能为null。现在,您并没有明确说明在这种情况下想要发生什么。您可能想要像这样:

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_idp.value的类型,这并没有帮助。(例如,如果product_id是值类型,则上面的代码需要做更多的工作。)


如果product_id是int类型,product_id = p == null ? null : p.product_id将无法编译。 - Alex Aza
1
@Alex:这就是为什么我写了最后一句话……如果product_id是一个字符串,你的版本将无法编译 :) - Jon Skeet
1
没有错误...像往常一样,Jon总是能够给出正确的答案并附上适当的解释。谢谢Jon。 - Dr. Rajesh Rolen

9
您正在进行左连接,因此 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,
            };

1
我在使用LINQ查询中LEFT JOIN多个表时遇到了相同的问题,我遇到了空引用异常。我使用了检查"?"来检查空值的技巧。如果我的方法不正确,请纠正我。
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
                             };

0

将您的模型类用作DefaultIfEmpty()函数的参数。

from p in cp.DefaultIfEmpty(new yourModelClass())

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接