我有三个单独的列表,这些列表是从不同的数据源填充的,现在我想在LINQ语句中将它们加入到我的最终结果中。但是,完全有可能其中一个列表可能是空的。看来如果列表为空,我不能只编写一个LINQ语句来加入其中任何一个。
我写了以下测试。我得到的错误是“NullReferenceException:对象引用未设置为对象的实例。”
// these colloections emulate the table structures and data
List<Agent> agents = new List<Agent>();
agents.Add(new Agent { AgentId = 1, ClientId = 11 });
agents.Add(new Agent { AgentId = 1, ClientId = 12 });
agents.Add(new Agent { AgentId = 1, ClientId = 13 });
agents.Add(new Agent { AgentId = 1, ClientId = 14 });
agents.Add(new Agent { AgentId = 2, ClientId = 21 });
agents.Add(new Agent { AgentId = 2, ClientId = 22 });
agents.Add(new Agent { AgentId = 3, ClientId = 31 });
List<Client> clients = new List<Client>();
clients.Add(new Client { ClientId = 11, ClientName = "A Client 11", Status = "A" });
clients.Add(new Client { ClientId = 12, ClientName = "A Client 12", Status = "A" });
clients.Add(new Client { ClientId = 13, ClientName = "A Client 13", Status = "A" });
clients.Add(new Client { ClientId = 14, ClientName = "A Client 14", Status = "A" });
clients.Add(new Client { ClientId = 21, ClientName = "A Client 21", Status = "A" });
clients.Add(new Client { ClientId = 22, ClientName = "A Client 22", Status = "A" });
clients.Add(new Client { ClientId = 31, ClientName = "A Client 31", Status = "A" });
// Upon initilization, there are no records here. Eventually, this "table" will be populated,
// but only after the user has used the app for a while. If I populate this list, it works assuming
// the agent ID I'm looking for is in the collection. But if it's not the join fails
List<ClientAdminFee> adminFees = new List<ClientAdminFee>();
// adminFees.Add(new ClientAdminFee { AgentId = 1, ClientId = 11, AdminFee = 0.05m, EffectiveFrom = DateTime.Parse("2017-01-01") });
// adminFees.Add(new ClientAdminFee { AgentId = 1, ClientId = 12, AdminFee = 0.05m, EffectiveFrom = DateTime.Parse("2017-01-01") });
// adminFees.Add(new ClientAdminFee { AgentId = 1, ClientId = 13, AdminFee = 0.05m, EffectiveFrom = DateTime.Parse("2017-01-01") });
// adminFees.Add(new ClientAdminFee { AgentId = 1, ClientId = 14, AdminFee = 0.05m, EffectiveFrom = DateTime.Parse("2017-01-01") });
var thisAgent = 1;
var theseAgents = agents.Where(x => x.AgentId == thisAgent).ToList();
var theseClients = clients.ToList();
var theseAdminFees = adminFees.Where(x => x.AgentId == thisAgent).ToList();
var final = (from ar in theseAgents
join c in theseClients on ar.ClientId equals c.ClientId
join caf in theseAdminFees on new { ar.AgentId, c.ClientId } equals new { caf.AgentId, caf.ClientId } into d
from caf in d.DefaultIfEmpty()
select new ClientWithAdminFee
{
AgentId = Convert.ToInt32(ar.AgentId),
ClientId = Convert.ToInt32(c.ClientId),
ClientName = c.ClientName,
Status = c.Status,
AdminFee = caf.AdminFee ?? 0.00m,
EffectiveDate = caf.EffectiveFrom ?? DateTime.Now
}).ToList();
final.Dump();
正如我所说的,如果我取消注释adminFees条目,并搜索AgentId 1,它就可以了。但是,如果我搜索不在该集合中的代理,我根本无法进行连接。那么我怎么能写这个如果它有条目,如果没有条目,它可以正常工作。
答案 0 :(得分:1)
试试这个
var final = (from ar in theseAgents
join c in theseClients on ar.ClientId equals c.ClientId
join caf in theseAdminFees on new { ar.AgentId, c.ClientId } equals new { caf.AgentId, caf.ClientId } into d
from caf in d.DefaultIfEmpty()
select new ClientWithAdminFee
{
AgentId = Convert.ToInt32(ar.AgentId),
ClientId = Convert.ToInt32(c.ClientId),
ClientName = c.ClientName,
Status = c.Status,
AdminFee = caf != null ? (caf.AdminFee) : 0,
EffectiveDate = caf != null ? (caf.EffectiveFrom == null ? DateTime.Now : caf.EffectiveFrom) : DateTime.Now,
}).ToList();