SingleOrDefault:仅捕获 "Sequence contains more than one element" InvalidOperationException

SingleOrDefault: Catch just "Sequence contains more than one element" InvalidOperationException

在我们的项目中,我们最近添加了一个旧数据导入工具,我们将这些旧数据转换为我们应用程序中可用的对象。在此导入中,我们有以下代码:

using (var session = documentStore.OpenSession())
{
    try
    {
        var cluster = session.Query<ClusterState>().SingleOrDefault(x => x.Name == clusterString);
        return cluster != null
            ? (ClusterId) cluster.AggregateId
            : null;
    }
    catch (InvalidOperationException e)
    {
        if (String.Equals(e.Message, "Sequence contains more than one element"))
        {
            Logger.Warn("More than one cluster found with the given string: {0}", clusterString);
            if (...)
            {
                return ...
            }
            return null;
        }

        throw;
    }
}

我的问题是以下一行:

if (String.Equals(e.Message, "Sequence contains more than one element"))

它在本地有效,但在服务器上无效。这样做的原因是我们有一个荷兰服务器,所以它提供了 "Reeks bevat meerdere elementen" InvalidOperationException 而不是 "Sequence contains more than one element"。现在我知道我可以将代码修改为:

if (String.Equals(e.Message, "Sequence contains more than one element")
    || String.Equals(e.Message, "Reeks bevat meerdere elementen"))

当然这行得通,我不认为我们打算在未来使用不同的语言服务器,但是,它仍然是非常糟糕的代码,如果消息随着新的 .NET / LINQ 版本而改变,这不再有效了。

那么,有没有其他方法可以只捕获 "Sequence contains more than one element" InvalidOperationException,而不捕获任何其他 InvalidOperationExceptions

我是否应该添加一个 Count 检查或其他东西来查看我是否收到了多个匹配元素而不是 Try-Catch,或者是否有一种独特的方法来过滤 "Sequence contains more than one element" 异常?或者我应该捕获所有 "InvalidOperationExceptions" 并添加一个额外的日志行以便我们收到这些异常的通知?

您可以将程序的文化设置为en-US可以解决您的问题

示例:

 // Change current culture
  CultureInfo culture;
  if (Thread.CurrentThread.CurrentCulture.Name == "fr-FR")
     culture = CultureInfo.CreateSpecificCulture("en-US");
  else
     culture = CultureInfo.CreateSpecificCulture("fr-FR");

  Thread.CurrentThread.CurrentCulture = culture;
  Thread.CurrentThread.CurrentUICulture = culture;

创建您的扩展方法并引发您自己的异常作为替代解决方案

public static TSource SingleOnlyOrDefault<TSource>(this IEnumerable<TSource> source,
        Func<TSource, bool> predicate)
    {
        if (source == null) { throw new ArgumentNullException("source"); }
        if (predicate == null) { throw new   
                         ArgumentNullException("predicate");    
    }

    IEnumerable<TSource> matchingItems = source.Where(predicate);
    int matchedItemCount = matchingItems.Count;

        switch (matchedItemCount)
        {
            case 0: return default(TSource);
            case 1: return matchingItems[0]; // Or Single() 
            default: throw new Exception("Too many element exist for    condition");
        }
    }