我正在编写一个方法(用于服务),该方法将特定错误代码返回给客户端。
在这个方法中,我调用了各种LINQ扩展方法。这些扩展方法中的每一种都可以抛出“相同”的例外情况。 type(比如public errorCode SomeMethod()
{
try
{
var foo1 = SomeDataSource.Entities1.Single(x=> x.bar1 == somevalue);
}
catch(InvalidOperationException x)
{
return ErrorCode1;
}
try
{
var foo2 = SomeDataSource.Entities2.Single(x=> x.bar2 > somevalue);
}
catch(InvalidOperationException x)
{
return ErrorCode2;
}
......
),但我需要单独捕获这些异常并返回特定的错误代码。这是现在的样子(简化版本)
foo
这加起来就是很多try-catch块,因为有几个可能存在的错误条件。它也迫使我将ACCEPT p_fletter PROMPT 'First letter: '
ACCEPT p_lletter PROMPT 'Last letter: '
DECLARE
CURSOR allCusts IS
SELECT name
FROM customer
WHERE name like "'||p_fletter||'%'||'p_lletter'"
BEGIN
-- call the above in some loop
END;
之类的变量范围提升到单个try块之外,因为它们在后续的try块中使用。
我只是想知道是否有办法以更优雅的方式整合所有这些代码(也许某些内联方法?),这样它最终看起来不那么令人生畏?
根据我得到的反馈,我必须补充一点,我正在尝试实施的商业规则让我使用' Single'而不是' SingleOrDefault'。使用' SingleOrDefault'使它更容易,因为我们可以检查null而不捕获异常。 '单'另一方面,如果条件失败,则只会抛出异常。这里的想法是巩固所有这些尝试块,即使每次调用单个'单独'单个'抛出相同类型的异常(InvalidOperationException)...
由于
答案 0 :(得分:4)
您滥用控制流的例外情况。更好:
var foo1 = SomeDataSource.Entities1.SingleOrDefault(x=> x.bar1 == somevalue);
if (foo1 == null) return ErrorCode1;
非常简洁。
原始代码中特别令人烦恼的是,您将所有InvalidOperationException
视为同一事物。谁知道这是不是真的?!抛出这种特殊异常类型可能有很多事情。你可能会过于慷慨地隐藏错误。你甚至可能用这种方式隐藏EF错误。
答案 1 :(得分:1)
如果您想将业务逻辑移动到lambda方法(听起来像这样),可以通过定义扩展来实现。
注意:我根本不支持下面的代码;我只是想让它适合你提出的问题。
public static class LinqExtensions
{
public static ErrorCode BusinessSingle(this IEnumerable<TSource> enumerable, Func<TSource, bool> predicate)
{
TSource result;
try
{
result = enumerable.Single(predicate);
return new NoError(); // ????
}
catch
{
return new ErrorOne();
}
}
}
但要做到以下其中一项会好得多:
Exception
,而是将其视为验证规则。Exception
。答案 2 :(得分:0)
你是对的,如果你总是期望只有一个元素符合你的条件,你应该使用Single()
而不是SingleOrDefault()
。
这意味着如果不是这种情况,那么您的系统就是一个故障状态,您的应用程序应该关闭,因为它无法正常工作。通过说Single()
,你会说&#34;我知道那里只有一个。如果没有,则会出现严重错误。&#34;
通过尝试处理异常并返回错误代码,您可以说出不同的内容。你在说&#34;那里应该只有一个,但如果没有,我可以做其他事来处理这个案子。&#34;这是SingleOrDefault()
的用途。