我将请求与基于requestId的响应进行匹配,如下所示:
public void MatchCallPairsByRequestId()
{
// Finds request that have matching response based on RequestId and create callpair
_callPairs = _requests.Where(req => !string.IsNullOrEmpty(req.RequestId))
.Join(_responses,
req => req.RequestId,
resp => resp.RequestId,
(req, resp) => new CallPair(req, resp)).ToList();
}
或在LINQ表达式中:
_callPairs = (from req in _requests
join resp in _responses
on req.RequestId equals resp.RequestId
where !string.IsNullOrEmpty(req.RequestId)
select new CallPair(req, resp)).ToList();
现在,我想在名为nonMatchedRequests
和nonMatchedResponses
的单独列表中收集与该功能不匹配的请求和响应。如何使用此查询在单独的列表中收集余数?
答案 0 :(得分:3)
我不确定是否有办法在一次调用中执行此操作,或者甚至将其与生成对列表合并,但您可以运行几个后续方法来确定不匹配的项:
var unmatchedRequests = _requests.Except(_callPairs.Select(cp => cp.Request));
var unmatchedResponses = _responses.Except(_callPairs.Select(cp => cp.Response));
Enumerable.Join
的文档也谈到能够使用GroupJoin
执行外部联接,如详细here,这将返回无法匹配的请求,但我认为它会错过无与伦比的响应。
我屏住呼吸地等待着答案,证明了linq巫术可以通过一次通话更有效地完成这项任务。
答案 1 :(得分:2)
查找返回的CallPair对象中不存在的请求和响应
var unmatchedRequests = _requests.Where(req => !_callPairs.Any(cp => cp.Request == req));
var unmatchedResponses = _responses.Where(resp => !_callPairs.Any(cp => cp.Response == resp));
编辑:这是一些示例代码
var requests = Enumerable.Range(0, 10).Select(i => "Request" + i).ToList();
var responses = Enumerable.Range(0, 10).Select(i => "Response" + i).ToList();
var pairs = Enumerable.Range(0, 3).Select(i => new KeyValuePair<string, string>("Request" + i, "Response" + i * 2)).ToList();
var unmatchedRequests = requests.Where(req => !pairs.Any(cp => cp.Key == req));
var unmatchedResponses = responses.Where(resp => !pairs.Any(cp => cp.Value == resp));
我得到7个不匹配的请求和7个不匹配的响应,看起来是正确的。您的某些请求是否与多个响应匹配,反之亦然?
答案 2 :(得分:2)
您可以通过.Except()
执行此操作,也可以使用不同的值
// Matching pairs
_callPairs = _requests.Where(req => !string.IsNullOrEmpty(req.RequestId))
.Join(
_responses,
req => req.RequestId,
resp => resp.RequestId,
(req, resp) => new CallPair(req, resp)
).ToList();
// To use the .Distinct() part, you're going to need to implement IEqualityComparer twice
// Easy but maybe not strictly necessary, no matter what it would be a solid approach
var matchedRequests = _callPairs.Select(cp => cp.Request); //.Distinct(new RequestComparer());
var matchedResponses = _callPairs.Select(cp => cp.Response); //.Distinct(new ResponseComparer());
var nonMatchingRequests = _requests.Except(matchedRequests);
var nonMatchingResponses = _responses.Except(matchedResponses);