使用linq进行验证/抛出异常

本文关键字:抛出异常 验证 linq 使用 | 更新日期: 2023-09-27 18:02:04

这可能是错误的方式做事情(!),但我只是想知道....

我使用

        //check that all transform fields have corresponding database columns
        foreach (string sDatabaseFieldName in l_sDatabaseFieldNames)
        {
            bool bFound = false;
            foreach (SqlParameter sqlp in sqlcmdAll.Parameters)
            {
                if (sqlp.SourceColumn == sDatabaseFieldName) bFound = true;
            }
            if (!bFound)
            {
                throw new Exception(string.Format("Transform field {0} does not have a corresponding column in the target table.", sDatabaseFieldName));
            }
        }

where l_sDatabaseFieldNames是一个列表<</p>

我想抛出一个异常,如果一个项目在l_sDatabaseFieldNames不是在任何sqlcmdall . parameters . sourcecoluml。换句话说,l_sDatabaseFieldNames中包含的所有列名也应该有一个匹配的参数(使用SourceColumn属性进行比较)。

我也可以用

bool bFound = l_sDatabaseFieldNames.All(sDBFN => sqlcmdAll.Parameters.Cast<SqlParameter>().Any(param => sDBFN == param.SourceColumn));

但我只得到一个正确/错误的结果。

我可以使用这两种技术的组合,并抛出一个异常从linq查询中,如果一个项目是在l_sDatabaseFieldNames,但不是在任何sqlcmdall . parameters . sourcecoluml ?

提前谢谢你,詹姆斯。

使用linq进行验证/抛出异常

您希望它抛出什么异常?我觉得您最好接受结果并抛出您想要抛出的异常:

if (!l_sDatabaseFieldNames.All(sDBFN => sqlcmdAll.Parameters.Cast<SqlParameter>().Any(param => sDBFN == param.SourceColumn)))
{
    throw new YourCustomException("Your custom message");
}
当然,如果这只是为了调试目的而验证测试中的条件,并且您不需要它进入实际的发布代码,则可以使用断言:
Debug.Assert(l_sDatabaseFieldNames.All(sDBFN => sqlcmdAll.Parameters.Cast<SqlParameter>().Any(param => sDBFN == param.SourceColumn)));

* UPDATE *

根据你的评论,你基本上有几个选择。我们可以使一个select子句变得庸俗,但我不喜欢这样,因为它在投射中感觉有点奇怪。遗憾的是,Linq还没有让您执行Action<T>ForEach(),因此您可以为IEnumerable<T>编写自己的ForEach(),或者您可以使用ToList()将序列转换为List<T>,其中确实有ForEach():
        sqlcmdAll.Parameters.Cast<SqlParameter>().ToList().ForEach(p =>
            {
                if (!l_sDatabaseFieldNames.Contains(p.SourceColumn))
                {
                    throw new Exception("Could not find " + p.SourceColumn);
                }
            });

如果你不介意编写自己的扩展方法,你可以将它添加到你的库中(非常方便),以将ForEach()赋给IEnumerable:

public static class EnumerableExtensions
{
    public static IEnumerable<T> ForEach<T>(this IEnumerable<T> source,
            Action<T> action)
    {
        if (source == null) throw new ArgumentNullException("source");
        foreach (T element in source)
        {
            action(element);
        }
        return source;
    }
}

这样你就不用使用ToList():

        sqlcmdAll.Parameters.Cast<SqlParameter>().ForEach(p =>
            {
                if (!l_sDatabaseFieldNames.Contains(p.SourceColumn))
                {
                    throw new Exception("Could not find " + p.SourceColumn);
                }
            });

可以选择第一个不匹配的参数

SqlParameter sqlp = sqlcmdAll.Parameters.Cast<SqlParameter>().Where(param => !l_sDatabaseFieldNames.Contains(param.SourceColumn)).FirstOrDefault();
if (sqlp != null)
    throw new Exception(string.Format("Transform field {0} does not have a corresponding column in the target table.", sqlp.SourceColumn));