我的asp.net MVC Web应用程序中包含以下代码:
var currentport = tms.TMSSwitchPorts
.Where(a => a.SwitchID == fromID)
.Select(a2 => a2.PortNumber)
.ToList();
if (currentport.Any(tms.TMSSwitchPorts
.Where(a => a.SwitchID == toID)
.Select(a => a.PortNumber)
.ToList()
)
)
{
// do something
}
但我无法以这种方式使用.Any()
,虽然我在两个列表中都选择了PortNumber字段?
有人可以提供建议吗?
答案 0 :(得分:4)
您可以使用简单的Join
:
var match = tms.TMSSwitchPorts.Where(a => a.SwitchID == fromID)
.Join(tms.TMSSwitchPorts.Where(a => a.SwitchID == toID),
(a) => a.PortNumber,
(b) => b.PortNumber,
(a, b) => true).Any();
if (match) { ... }
生成的SQL应该看起来像
SELECT
(CASE
WHEN EXISTS(
SELECT NULL AS [EMPTY]
FROM [TMSSwitchPorts] AS [t0]
INNER JOIN [TMSSwitchPorts] AS [t1] ON [t0].[PortNumber] = [t1].[PortNumber]
WHERE ([t0].[SwitchID] = @p0) AND ([t1].[SwitchID] = @p1)
) THEN 1
ELSE 0
END) AS [value]
所以,如果您没有任何数据需要单个1
或0
移动电话,那么您就不必弄乱应用程序内存。
代码
if (currentport.Any(tms.TMSSwitchPorts
.Where(a => a.SwitchID == toID)
.Select(a => a.PortNumber)
.ToList()
)
不起作用,因为Any
期望Func<T, bool>
形式的谓词,但是您传递List<Int>
(假设PortNumber
是int
)
答案 1 :(得分:1)
取SwitchID == toID
的类似列表。
var alreadyUsed = tms.TMSSwitchPorts
.Where(a => a.SwitchID == toID)
.Select(a2 => a2.PortNumber)
.ToList();
然后检查两个列表中是否都没有出现。
if (currentPort.Intersect(alreadyUsed).Any())
{ // do something }
Any()
并不像您认为的那样工作。如上所述,它本身检查容器中的任何元素。如@ BenAaronson的答案(比这个答案稍好一点)所示,它检查IEnumerable
是否包含函数参数返回true的任何元素。
list1.Any(HasSomeProperty)
其中HasSomeProperty
是一个函数,它接受list1
的元素并返回一个bool;或更多通常使用lambda:
list1.Any(x => SomePropertyHoldsFor(x))
我说@ BenAaronson的回答更好,因为它允许一些短路&#39;优化,我没有想到我的解决方案。这些在他的回答的评论中提到。但是,通过一些反复试验,我发现Intersect会自动进行相同的优化 - 特别是它会缓存&#39;输出&#39;一个IEnumerable用于与另一个元素的每个元素进行比较,而不是每次遍历它。所以我的解决方案更好,因为Intersect
会自动为你的方法做一些思考; @懒惰的答案涉及不同的自动优化,并且更好对于使用Queryable
的数据库查询,请问者想到了。
This answer explains how Intersect
works - 它实际上不是“缓存”,但它只访问每个IEnumerable
一次。
答案 2 :(得分:1)
根据jwg的评论,您可以使用Contains
匹配检查第一组端口(From)和第二组(to)之间是否匹配:
var fromPorts = tms.TMSSwitchPorts
.Where(a => a.SwitchID == fromID)
.Select(a2 => a2.PortNumber);
if (tms.TMSSwitchPorts
.Any(a => a.SwitchID == toID &&
fromPorts.Contains(a.PortNumber)))
答案 3 :(得分:0)
如果你的目标是他的评论中描述的jwg,你可以这样做:
var currentportFrom = tms.TMSSwitchPorts
.Where(a => a.SwitchID == fromID)
.Select(a2 => a2.PortNumber)
.ToList();
var currentportTo = tms.TMSSwitchPorts
.Where(a => a.SwitchID == fromID)
.Select(a2 => a2.PortNumber)
.ToList();
if(currentportFrom.Any(cp => currentportTo.Contains(cp))
{
//do something
}