Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在两个ienumerables之间使用任意_C#_Linq_Entity Framework_Asp.net Mvc 4 - Fatal编程技术网

C# 如何在两个ienumerables之间使用任意

C# 如何在两个ienumerables之间使用任意,c#,linq,entity-framework,asp.net-mvc-4,C#,Linq,Entity Framework,Asp.net Mvc 4,我的asp.net MVC web应用程序中包含以下代码: var currentport = tms.TMSSwitchPorts .Where(a => a.SwitchID == fromID) .Select(a2 => a2.PortNumber) .ToList(); if (currentport.Any(tms.TMSS

我的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字段


有人能提供建议吗?

如果您的目标是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
}

如果您的目标如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
}

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的答案更好,因为它允许一些我认为我的解决方案没有的“短路”优化。这些都在对他的答复的评论中提到。然而,通过一些尝试和错误,我发现Intersect确实会自动进行相同的优化——特别是它缓存一个IEnumerable的“输出”,以便与另一个IEnumerable的每个元素进行比较,而不是每次都遍历它。因此,我的解决方案更好,因为
Intersect
会自动完成您需要考虑的Ben方法;)@sloth的答案涉及到一种不同的自动优化,而且对于使用询问者心目中的
Queryable
进行数据库查询来说,这要好得多


-它不是真正的“缓存”,但它只访问每个
IEnumerable
一次。

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的答案更好,因为它允许一些我认为我的解决方案没有的“短路”优化。这些都在对他的答复的评论中提到。然而,通过一些尝试和错误,我发现Intersect确实会自动进行相同的优化——特别是它缓存一个IEnumerable的“输出”,以便与另一个IEnumerable的每个元素进行比较,而不是每次都遍历它。因此,我的解决方案更好,因为
Intersect
会自动完成您需要考虑的Ben方法;)@sloth的答案涉及到一种不同的自动优化,而且对于使用询问者心目中的
Queryable
进行数据库查询来说,这要好得多


-它不是真正的“缓存”,但它只访问每个
IEnumerable
一次。

根据jwg的评论,您可以使用
包含的匹配项检查第一组端口(从)和第二组端口(到)之间是否匹配:

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)))

根据jwg的评论,您可以使用
包含
匹配项检查第一组端口(从)和第二组端口(到)之间是否匹配:

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)))

您可以使用一个简单的
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
形式的谓词,但您可以向它传递一个
列表(假设
PortNumber
是一个
int
)。

您可以使用简单的
连接在数据库中高效且完全地执行此操作:

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
形式的谓词,但您向它传递一个
列表(假设
PortNumber
int
).

你想做什么?@ThomasLevesque我想确保当前端口号中没有一个已经分配给switchID==toID思考一下:如果
switchID
fromID
,那么它就不能是
toID
,除非
fromID==toID
。。。所以你只需要测试它。@ThomasLevesque,不,他正在测试是否有任何元素具有
SwitchID==fromID
PortNumber==X
,其中其他元素具有
SwitchID=toID
PortNumber==X
(对于任何X)。@jwg,也许。。。很难从当前代码猜出您想做什么?@ThomasLevesque我想确保当前端口号中没有一个已经分配给switchID==toID思考一下:如果
switchID
fromID
,那么它就不能是
toID
,除非
fromID==toID
。。。所以你只需要测试它。@ThomasLevesque,不,他正在测试是否有任何元素具有
SwitchID==fromID
PortNumber==X
,其中其他元素具有
SwitchID=toID
PortNumber==X
(对于任何X)。@jwg,也许。。。很难从当前的代码中猜到,但通过这种方式,我将从数据库中检索所有记录,我试图做的是发布