我将请求与基于requesttid的响应进行匹配,如下所示:
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
的单独列表中收集与函数不匹配的请求和响应。如何使用此查询在单独的列表中收集其余部分?
我不确定是否有一种方法可以在一次调用中完成此操作,或者甚至可以将其与生成配对列表合并,但是您可以运行几个后续方法来确定不匹配的项:
var unmatchedRequests = _requests.Except(_callPairs.Select(cp => cp.Request));
var unmatchedResponses = _responses.Except(_callPairs.Select(cp => cp.Response));
Enumerable.Join
的文档还谈到了能够使用GroupJoin
执行外部连接,如这里所述,这将返回不匹配的请求,尽管我认为它会错过不匹配的响应。
我屏住呼吸等待答案演示linq魔法,更有效地完成这个调用
你可能可以通过.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);
查找返回的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个不匹配的响应,这看起来是正确的。您的一些请求是否会被匹配到多个响应,反之亦然?