LINQ:如何获得两组int的交集?

时间:2015-10-28 18:29:46

标签: c# database linq intersection

必须有一种方法可以在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");
        }
    }

想法?感谢。

1 个答案:

答案 0 :(得分:0)

简单回答(这将产生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()) {}