我有一个列表和两个表。 (这是实际模式的一个非常简化的版本,但应该适用于该问题)
List_A
FPI
1
2
3
4个
表-B
FPI_______NI
2_________1
4_________2
Table_C
NI_______Name
1_________x
2_________y
我的linq查询:
(from a in List_A
join b in Table_B on a.FPI equals b.FPI into ab
from b in ab.DefaultIfEmpty()
join c in Table_C on b.FI equals c.FI into bc
from c in bc.DefaultIfEmpty()
select new {
FPI = a.FPI,
Name = c?.Name}).ToList();
此代码抛出Object reference not set to an instance of an object.
的异常。
经过大量的试验和实验,我得出的结论是,在第二次加入时我正在进行b.FI equals c.FI
,那时对于Table_B中没有值的条目失败了。< BR />
查询的预期输出应为
的 ABC
FPI____NI___Name
1_____null__null
2_____1_____x
3_____null__null
4_____2_____y
我不确定为什么会出现这个错误以及这个问题的最佳解决方案。
答案 0 :(得分:0)
你可以尝试
var list=(from a in Table_A
join b in Table_B on a.FPI equals b.FPI into ab
from b in ab.ToList()
join c in Table_C on b.NI equals c.NI into bc
from c in bc.DefaultIfEmpty()
select new {
FPI = a.FPI,
Name = c.Name}).ToList();
<强>更新强>
var list = (from a in Table_A
join b in Table_B on a.FPI equals b.FPI into ab
from b in ab.DefaultIfEmpty()
join c in Table_C on b == null ? 0 : b.NI equals c.NI into bc
from c in bc.DefaultIfEmpty()
select new
{
FBI = a.FPI,
NI = c != null ? c.NI : null,//if NI is nullable
//NI = c != null ? c.NI : 0,//if NI is not nullable
Name = c!=null?c.Name:null
}).ToList();
答案 1 :(得分:0)
如果将LINQ to Entities查询转换为SQL,您的查询将完全有效。
但是,由于查询的根目录List_A
不是IQueryable
,因此整个查询在LINQ to Objects上下文中执行,您应该在其中执行null
检查左外连接的右侧变量,包括进一步的连接条件。
所以简单的解决方法就是使用
join c in Table_C on b?.FI equals c.FI into bc
但请注意,查询效率极低。由于已经解析为Enumerable
方法,因此整个Table_B
和Table_C
将在内存中读取,然后加入。
更好的方法是将db和内存查询分开:
var dbQuery =
from b in Table_B
join c in Table_C on b.FI equals c.FI into bc
from c in bc.DefaultIfEmpty()
select new { b.FPI, c.Name };
var query =
from a in List_A
join bc in dbQuery on a.FPI equals bc.FPI into abc
from bc in abc.DefaultIfEmpty()
select new
{
FPI = a.FPI,
Name = bc?.Name
};
var result = query.ToList();