我知道这个错误意味着什么,但我不知道如何在我的LINQ语句中修复它。
ScannerMessages是一本字典。其中的值可以是串行扫描中的数字,也可以是string.empty,或者(在任何扫描发生之前)为null。我有一种感觉,有人会说使用FirstorDefault(),但我不能使用null / string.empty的默认值。我尝试使用
.Any(x => !string.IsNullOrEmpty(x.Value)).
但这会返回一个bool并且是错误的检查。我觉得我需要一个Where()但我已经尝试过这一点也无济于事(我也试过改变我的GroupBy()子句)。我觉得我很接近,但我不确定在哪里修改我的表达。
注意:这是在一个锁中,所以我知道当我查询它时,我的其他线程都没有影响字典(ScannerMessages被锁定)
public ScanType equalMessages()
{
try
{
lock (lckObj)
{
if (_scannersPresent)
{
// Check to see if message that came through was caught in the buffer. If it has it will be equal to the previous message.
if (ScannerMessages.GroupBy(x => x.Value).Where(x => x.Count() > 1).First().Key == _holdMsg) return ScanType.ClearBuffer;
// If all messages are null or empty no scan
else if (ScannerMessages.Values.All(s => string.IsNullOrEmpty(s))) return ScanType.NoScan;
// If there is only one scanner then all scans must be determined to be either MATNUM or a rescan of an LPN
else if (_ScannerCount == 1) return ScanType.DiscernScanType;
// If distinct count of non null/empty values is less than total count of all non null/empty values, then scan is good
else if (ScannerMessages.Values.Distinct().Count(v => !string.IsNullOrEmpty(v)) < ScannerMessages.Values.Count(v => !string.IsNullOrEmpty(v)))
{
// This condition is only met if there is more than one of the same scan, and therefore is not a reprint. Pad all values with '0's for proper MATNUM format
ScannerMessages = ScannerMessages.Where(x => !string.IsNullOrEmpty(x.Value)).ToDictionary(x => x.Key, x => x.Value.PadLeft(18, '0'));
return ScanType.GoodScan;
}
// If non null/empty counts is equal to one, and the message is not the same as previous scan, then message was not from buffer and is LPN for reprint
else if ((ScannerMessages.Values.Distinct().Count(v => !string.IsNullOrEmpty(v)) == 1) && (ScannerMessages.GroupBy(x => x.Value).Where(x => x.Count() > 1).First().Key != _holdMsg)) return ScanType.Reprint;
else return ScanType.NoScan;
}
return ScanType.NoScan;
}
}
catch (Exception ex) {
myEvents.raiseErrorMessageBox(ex.Message);
throw new Exception(ex.Message, ex); }
}
编辑:我不确定哪一行引发了错误 - 我认为它是第一个if行或最后的else如果在else返回ScanType.NoScan之前。这些是使用First()调用的唯一语句。问题是大约每半秒调用一次,因此调试它会备份。有3个线程访问ScannerMessages字典,然后调用此字符的线程检查该字典。当我有4个线程命中它时,我不确定如何调试它。我唯一知道的是它是*线程安全的:/如果我试图在第一行放置一个断点,它会击中很多次,而当我踩到时我会错过任何“真正的”扫描。
答案 0 :(得分:1)
ScannerMessages.GroupBy(x => x.Value).Where(x => x.Count() > 1).First()
那么如果没有包含多于1个元素的组呢?您认为应该怎么做?
您应该将这些条件分成更小的步骤,而不是试图将所有内容都放在单个表达式中。在这种情况下,我建议使用FirstOrDefault
并将条件替换为:
var value = ScannerMessages.GroupBy(x => x.Value).Where(x => x.Count() > 1).FirstOrDefault()
if (value != null && value.Key == _holdMsg) return ScanType.ClearBuffer;
答案 1 :(得分:0)
我不知道我是否需要重新提出这个问题,但我能够使用这个 - 如果对#34;精简&#34;有任何修改。它会很棒 - 我觉得抓住kvp.Value.Vlaue有点多余,但我又不知道怎么回答&#34;问题具体来说,这就是我所需要的。
class testing
{
private Dictionary<string, string> dict = new Dictionary<string, string>();
private Dictionary<string, string> _dict = new Dictionary<string, string>();
private Dictionary<string, string> __dict = new Dictionary<string, string>();
public testing()
{
dict.Add("stringA", string.Empty);
dict.Add("stringB", "123456");
dict.Add("stringC", string.Empty);
_dict.Add("stringA", string.Empty);
_dict.Add("stringB", string.Empty);
_dict.Add("stringC", string.Empty);
__dict.Add("stringA", "654321");
__dict.Add("stringB", "123456");
__dict.Add("stringC", string.Empty);
checkDict(dict, "dictionary1");
checkDict(_dict, "dictionary2");
checkDict(__dict, "dictionary3");
}
private void checkDict(Dictionary<string,string> myDict, string s)
{
try
{
var exam = dict.Where(x => !string.IsNullOrEmpty(x.Value)).ToDictionary(x => x.Key);
foreach (var kvp in exam)
{
Console.WriteLine(kvp.Value.Value);
}
}
catch(Exception ex)
{
eh(ex);
}
}
private void eh(Exception ex)
{
Console.WriteLine(ex.Message);
if (ex.InnerException != null) eh(ex.InnerException);
}
}