上图是我ListN
的示例数据。
我还有另一个列表ListA
,其中有两个项目{ID=1090,ID=1089}
现在我有以下代码:
CODEa所
var x = 0;
foreach(var item in ListA){
if(ListN.Where(x=>x.ID==item.ID).Any(y=>y.Data != null))
{
x = ListN.Where(x=>x.ID==item.ID).Min(y=>y.Data).Value;
break;
}
}
CodeB:
var x = 0;
foreach(var item in ListA){
var list = ListN.Where(x=>x.ID==item.ID);
if(list.Any(y=>y.Data != null))
{
x = list.Min(y=>y.Data).Value;
break;
}
}
有人可以向我解释为什么 CodeA 错误地抛出null异常,但 CodeB 正常工作?
答案 0 :(得分:2)
不是问题的答案。但这是实现你想要做的事情的可怕方式......
var x = (from item in ListA
join list in ListN on item.ID equals list.ID
where list.Data != null
select list.Data).Min();
你的意思更清楚了。此外,Linq编译器实际上会为您生成更优的代码(因为它将使用哈希查找)。
你遇到的主要问题是你试图将命令式编程(foreach,break等)与声明式编程(Where,Min等)混淆并让自己感到困惑。
答案 1 :(得分:1)
这是因为您在第一个If
条件中测试了空值,但在第二个中您无视该测试并再次选择与Where
子句匹配的项目。
您在第二个选择中没有获得与第一个测试中相同的列表。
在CodeB
示例中,您只处理绝对没有空数据字段的项目。
我建议做这样的事情:
var x = 0;
foreach(var item in ListA)
{
var list = ListN.Where(x=> x.ID == item.ID && x.Data != null).ToList();
if(list.Any())
{
x = list.Min(y=>y.Data).Value;
break;
}
}
答案 2 :(得分:1)
这是不的答案。但它太大了,无法发表评论。
我无法重现你的问题。我不知道这两个答案是什么声称在一个样本中发生某种形式的“更多过滤”而不是另一个样本。
这是您的代码,一些修正(因为您不能拥有var x
并使用x
作为lambda参数)和您的数据。它输出No Exception
两次,表明两个代码示例运行良好:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security;
namespace ConsoleApplication4
{
class Program
{
class N
{
public int ID { get; set; }
public int? Data { get; set; }
}
class A
{
public int ID { get; set; }
}
static int CodeA(List<N> ListN, List<A> ListA)
{
var c = 0;
foreach (var item in ListA)
{
if (ListN.Where(x => x.ID == item.ID).Any(y => y.Data != null))
{
c = ListN.Where(x => x.ID == item.ID).Min(y => y.Data).Value;
break;
}
}
return c;
}
static int CodeB(List<N> ListN, List<A> ListA)
{
var c = 0;
foreach (var item in ListA)
{
var list = ListN.Where(x => x.ID == item.ID);
if (list.Any(y => y.Data != null))
{
c = list.Min(y => y.Data).Value;
break;
}
}
return c;
}
static void Main(string[] args)
{
var listN = new List<N>
{
new N {ID = 1090, Data = 1},
new N {ID = 1090, Data = 3},
new N {ID = 1090, Data = 4},
new N {ID = 1089, Data = 1},
new N {ID = 1089, Data = 3},
new N {ID = 1089, Data = 4},
new N {ID = 1089, Data = null}
};
var listA = new List<A>
{
new A {ID = 1089},
new A {ID = 1090}
};
try
{
CodeA(listN, listA);
Console.WriteLine("No Exception");
}
catch (Exception ex)
{
Console.WriteLine("A exception: " + ex.ToString());
}
try
{
CodeB(listN, listA);
Console.WriteLine("No Exception");
}
catch (Exception ex)
{
Console.WriteLine("B exception: " + ex.ToString());
}
Console.ReadLine();
}
}
}
如果您希望获得有关实际问题的帮助,请参考上面的代码示例并对CodeA
引发您所讨论的此异常以及CodeB
没有引发异常的情况进行适当的更改。然后,您可以将其纳入您的问题,我将删除此“答案”。