【问题标题】:LINQ: how to get an intersection of two sets of ints?LINQ:如何获得两组整数的交集?
【发布时间】:2015-10-28 18:29:46
【问题描述】:

在 LINQ 中必须有一种方法可以比较两组结果。这是我现有的代码,它使用 HashSet 在两个单独的查询后进行比较:

    public static void AssertDealershipsShareTransactionGatewayCredentialIds(long DealershipLocationId1,
        long DealershipLocationId2)
    {
        using (var sqlDatabase = new SqlDatabaseConnection())
        {
            var DealershipCredentials1 =
                sqlDatabase.Tables.DealershipLocationTransactionGateway
                    .Where(x => x.DealershipLocationId == DealershipLocationId1)
                    .Select(x => x.TransactionGatewayCredentialId);
            var DealershipCredentials2 =
                sqlDatabase.Tables.DealershipLocationTransactionGateway
                    .Where(x => x.DealershipLocationId == DealershipLocationId2)
                    .Select(x => x.TransactionGatewayCredentialId);
            var doSetsOfCredentialsMatch = new HashSet<int>(DealershipCredentials1).SetEquals(DealershipCredentials2);
            Assert.IsTrue(doSetsOfCredentialsMatch,
                "The sets of TransactionGatewayCredentialIds belonging to each Dealership did not match");
        }
    }

想法?谢谢。

【问题讨论】:

标签: c# database linq intersection


【解决方案1】:

简单的答案(这将进行 1 次,可能 2 次数据库调用,两者都只返回一个布尔值):

if (list1.Except(list2).Any() || list2.Except(list1).Any()) 
{
   ... They did not match ...
}

更好的答案(这将使 1 个数据库调用返回一个布尔值):

var DealershipCredentials1 =
  sqlDatabase.Tables.DealershipLocationTransactionGateway
    .Where(x => x.DealershipLocationId == DealershipLocationId1)
    .Select(x => x.TransactionGatewayCredentialId);
var DealershipCredentials2 =
  sqlDatabase.Tables.DealershipLocationTransactionGateway
    .Where(x => x.DealershipLocationId == DealershipLocationId2)
    .Select(x => x.TransactionGatewayCredentialId);
if (DealershipCredentials1.GroupJoin(DealershipCredential2,a=>a,b=>b,(a,b)=>!b.Any())
    .Union(
      DealershipCredentials2.GroupJoin(DealershipCredential1,a=>a,b=>b,(a,b)=>!b.Any())
    ).Any(a=>a))
{
... They did not match ...
}

第二种方法通过联合一个左外连接来工作,该左外连接返回一个布尔值,指示是否找到了与执行相同操作的右外连接的任何不匹配记录。我还没有测试过,但理论上它应该从数据库中返回一个简单的布尔值。

另一种方法,与第一种方法基本相同,但包装在单个 LINQ 中,因此它始终只会进行 1 次数据库调用:

if (list1.Except(list2).Union(list2.Except(list1)).Any())
{
}

还有另一种方法:

var common=list1.Intersect(list2);
if (list1.Except(common).Union(list2.Except(common)).Any()) {}

【讨论】:

  • Intersect 会不会更简单?在任何情况下,这两种方法(或Contains)都不适用于任何类。
  • Intersect 只会返回两个集合中的记录,不会告诉您是否有任何记录在一个集合中,而不是两个集合。
猜你喜欢
  • 1970-01-01
  • 2016-03-23
  • 1970-01-01
  • 1970-01-01
  • 2021-10-06
  • 1970-01-01
  • 2015-12-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多