【问题标题】:Is there a way to break out of a LINQ SELECT on completion of a custom WHERE Clause有没有办法在自定义 WHERE 子句完成时打破 LINQ SELECT
【发布时间】:2011-11-12 00:18:28
【问题描述】:

我有一个 LINQ 语句,它使用自定义函数在压缩字符串中查找某些匹配数据。

只有一个匹配项,如果我做了一个 FOR 循环,我会在找到数据后添加一个“中断”。但是,使用 LINQ 似乎会遍历所有记录以查找是否需要匹配(从 SQL/子集的角度来看这是有道理的)但是我想知道是否有办法让 LINQ 语句在完成时中断WHERE 子句,这样它就不必在找到单个匹配项后继续搜索匹配的记录。

我可以重新编写它以使用 FOR 循环,但我想知道是否有一种方法可以限制 LINQ 语句,如果条件匹配,则在 X 次迭代后停止搜索。

代码如下

    IEnumerable<MarketDataType> queryMarkets =
            from m in Mdata
            where !String.IsNullOrEmpty(m)
            let field = m.Split('~')
            where (MatchMarket(field[5], BaseDate.AddMilliseconds(DaylightSavings + Convert.ToDouble(field[4])), field[1], racecourse, racedatetime, marketType))
            select new MarketDataType()
            {
                marketId = Convert.ToInt32(field[0]),
                marketName = field[1].Replace(ColonCode, ":"),
                marketType = field[2],
                marketStatus = field[3],
                eventDate = BaseDate.AddMilliseconds(DaylightSavings + Convert.ToDouble(field[4])),
                menuPath = field[5].Replace(ColonCode, ":"),
                eventHeirachy = field[6],
                betDelay = Convert.ToInt32(field[7]),
                exchangeId = Convert.ToInt32(field[8]),
                countryCode = field[9],
                lastRefresh = BaseDate.AddMilliseconds(DaylightSavings + Convert.ToDouble(field[10])),
                noOfRunners = Convert.ToInt32(field[11]),
                noOfWinners = Convert.ToInt32(field[12]),
                totalAmountMatched = Convert.ToDouble(field[13]),
                bspMarket = (field[14] == "Y"),
                turningInPlay = (field[15] == "Y")
            };

        marketData = queryMarkets.ToList();

我是否可以添加另一个 WHERE 子句,以某种方式查看我的 IEnumerable 对象 MarketDataType 以确保如果存在一行则将其忽略?或者将其重写为 foreach/for 循环是最好的方法。

任何帮助将不胜感激。谢谢

【问题讨论】:

    标签: c# .net linq ienumerable betfair


    【解决方案1】:

    别忘了TakeTakeWhile

    来自 TakeWhile...

    只要指定条件为真,就从序列中返回元素,然后跳过其余元素。

    【讨论】:

      【解决方案2】:

      听起来你想要First()FirstOrDefault()Single()SingleOrDefault()

      MarketDataType result = queryMarkets.FirstOrDefault();
      

      (如果只有一个结果,所有这些方法都会给您相同的结果;它们在处理零个或多个结果时有所不同。)

      【讨论】:

      • 感谢您的回复,但我对 LINQ 还很陌生,您能否给我提供的编辑示例以及您提到的代码的位置。我猜你必须将它添加到某个地方的主 LINQ 语句中,否则它仍然会循环遍历整个集合以创建子集?
      • @user1037545:只需替换您当前的最后一行代码。您根本不需要更改 queryMarkets 的声明。 LINQ 被延迟评估 - 声明 queryMarkets 的语句只是设置查询 - 只有当您开始评估它实际运行的结果时。但是,如果您是 LINQ 新手,我建议您从比当前大查询稍微简单的内容开始:)
      • 好吧,我是 LINQ 的新手,但有 15 年以上的 SQL 经验,所以我的印象是它是一种非常相似的迭代多种类型数据集的方法。该代码已经工作了一年多,但我只是在调试期间注意到,即使当天的第一场比赛在 LINQ 开始时匹配,如果我在 MatchMarket 函数中放置一条日志消息,所有其他比赛仍在查看这似乎浪费了循环迭代。感谢您的帮助
      • @user1037545:忽略“它看起来有点像 SQL”部分 - 将 LINQ 学习为 LINQ;它的习语,它的执行模型等等。
      • 我实际上得到“未处理的异常:System.NullReferenceException:对象引用未设置为对象的实例。”错误现在我在以前没有的地方添加了该代码?
      【解决方案3】:

      只需在IEnumerable 上使用First() 而不是ToList(),这将在第一场比赛后停止评估。

      【讨论】:

        猜你喜欢
        • 2021-12-25
        • 2012-03-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-13
        • 1970-01-01
        相关资源
        最近更新 更多