【问题标题】:LINQ lambda expression throws Sequence contains no elementsLINQ lambda 表达式抛出序列不包含任何元素
【发布时间】:2014-06-24 20:24:54
【问题描述】:

我知道这个错误意味着什么,但我不确定如何在我的 LINQ 语句中修复它。

ScannerMessages 是一个字典。这里的值要么是来自串行扫描的数字,要么是 string.empty,要么是(在任何扫描发生之前)null。我感觉有人会说要使用 FirstorDefault(),但我不能使用 null/string.empty 的默认值。我尝试使用

.Any(x => !string.IsNullOrEmpty(x.Value)). 

但这会返回一个布尔值并且是错误的检查。我觉得我需要一个 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 if 在 else 返回 ScanType.NoScan 之前。这些是使用 First() 调用的唯一语句。问题是大约每半秒调用一次,因此调试它会备份。有 3 个线程访问 ScannerMessages 字典,然后调用它的线程检查该字典。当我有 4 个线程访问它时,我不确定如何调试它。我唯一知道的是它是*线程安全的:/如果我尝试在第一行放置一个断点,它会命中很多次,以至于当我单步执行时,我会错过任何“真实”扫描。

【问题讨论】:

  • 哪一行报错?
  • @Blorgbeard 我在我认为问题发生的地方添加了 - 评论回复太长了。
  • FWIW,如果我理解 FirstOrDefault() 它将获取 string.empty|null。我需要的是获取 First().Key.Where(x => !string.IsNullOrEmpty(x.Value) 但这也不起作用。例如字典可能是 , , 。根据我对我的陈述的理解,它会抛出这个错误,但我又不能做 First() 或 FirstOrDefault()

标签: c# linq lambda


【解决方案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;

【讨论】:

  • 我认为这正是我所需要的,你是说没有办法将它添加到 lambda 表达式中吗?如果没有包含超过 1 个元素的组,则它属于规范逻辑,它应该返回 ScanType.NoScan(最后一个 else 语句)
  • 您忘记将First 替换为FirstOrDefault
  • 我不想要 FirstOrDefault ,因为这会给我一个 string.empty 或 null 等待到目前为止已触发的线程。我需要它基本上过滤掉任何字符串。空或空值
  • 我想直接回答你的问题“你认为应该发生什么?”它是否应该将 if 子句作为评估假来逃避。抱歉,我在第一次回复您时没有回答这个问题。
【解决方案2】:

我不知道我是否需要重新提出问题,但我能够使用它来获得它 - 如果有任何修改来“简化”它会很棒 - 我觉得抓住了 kvp。 Value.Vlaue 有点多余,但我不知道如何具体“回答”这个问题,这让我得到了我需要的东西。

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);
    }
}

【讨论】:

    猜你喜欢
    • 2016-12-06
    • 1970-01-01
    • 1970-01-01
    • 2012-10-29
    • 1970-01-01
    • 2011-09-01
    • 2014-12-25
    • 1970-01-01
    • 2012-04-12
    相关资源
    最近更新 更多