序列中没有匹配的元素 [英] Sequence contains no matching element

查看:137
本文介绍了序列中没有匹配的元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我使用的数据操作LINQ一个asp.net应用程序。 。在运行时,我得到的异常序列中没有匹配的元素

 如果(_lstAcl.Documents.Count大于0) 
{
为(i = 0; I< = _lstAcl.Documents.Count - 1;我++)
{
字符串ID = _lstAcl.Documents [I] .ID。的ToString();
VAR documentRow = _dsACL.Documents.First(O => o.ID == ID);
如果(documentRow!= NULL)
{

_lstAcl.Documents [I] .Read = documentRow.Read;
_lstAcl.Documents [I] .ReadRule = documentRow.ReadRule;

_lstAcl.Documents [I] .Create = documentRow.Create;
_lstAcl.Documents [I] .CreateRule = documentRow.CreateRule;

_lstAcl.Documents [I] .Update = documentRow.Update;
_lstAcl.Documents [I] .UpdateRule = documentRow.UpdateRule;

_lstAcl.Documents [I] .Delete = documentRow.Delete;
_lstAcl.Documents [I] .DeleteRule = documentRow.DeleteRule;
}
}
}


解决方案

好了,我希望它是这行的抛出异常:

  VAR documentRow = _dsACL.Documents.First (O => o.ID == ID)

第一() 将抛出,如果它不能例外找不到任何匹配的元素。假设你正在为空之后立即进行测试,这听起来像你想 FirstOrDefault( ) ,该返回元素类型的默认值(这是空的引用类型),如果未找到匹配项目:

  VAR documentRow = _dsACL.Documents.FirstOrDefault(O => o.ID == ID)

其他选项,在某些情况下考虑的是 单() (当你相信有完全一个匹配的元素)和 的SingleOrDefault() (当你相信有只有一个或零匹配元素)。我怀疑 FirstOrDefault 是在这种特殊情况下,最好的选择,但它是值得了解的人反正。



在另一方面,它看起来像你实际上可能是摆在首位用参加在这里更好。如果你不关心它会做的所有的匹配(而不只是第一个),你可以使用:

  VAR的查询=从目标中_lstAcl.Documents 
在_dsAcl.Document
,其中source.ID.ToString()等于target.ID
选择新的{源,目标}加入源;
的foreach(查询VAR对)
{
target.Read = source.Read;
target.ReadRule = source.ReadRule;
//等
}

这是简单的更有效的IMO



即使你的的决定保持环路,我有几个建议:




  • 摆脱外如果的。你不需要它,仿佛计数为零的for循环的身体会不会执行

  • 使用独有的上限为循环 - 他们在C#中更地道:

     为(i = 0; I< _lstAcl.Documents.Count;我++)


  • 消除常见的子表达式:

      VAR的目标= _lstAcl.Documents [I] 
    //现在使用目标循环体
    的其余


  • 如果可能的话使用的foreach 而不是来开始:

     的foreach(在_lstAcl.Documents VAR目标)



I have an asp.net application in which I am using linq for data manipulation. While running, I get the exception "Sequence contains no matching element".

if (_lstAcl.Documents.Count > 0)
{
    for (i = 0; i <= _lstAcl.Documents.Count - 1; i++)
    {
        string id = _lstAcl.Documents[i].ID.ToString();                           
        var documentRow = _dsACL.Documents.First(o => o.ID == id);
        if (documentRow !=null)
        {

            _lstAcl.Documents[i].Read = documentRow.Read;
            _lstAcl.Documents[i].ReadRule = documentRow.ReadRule;

            _lstAcl.Documents[i].Create= documentRow.Create;
            _lstAcl.Documents[i].CreateRule = documentRow.CreateRule;

            _lstAcl.Documents[i].Update = documentRow.Update;
            _lstAcl.Documents[i].UpdateRule = documentRow.UpdateRule;

            _lstAcl.Documents[i].Delete = documentRow.Delete;
            _lstAcl.Documents[i].DeleteRule = documentRow.DeleteRule;
        }
    }
}

解决方案

Well, I'd expect it's this line that's throwing the exception:

var documentRow = _dsACL.Documents.First(o => o.ID == id)

First() will throw an exception if it can't find any matching elements. Given that you're testing for null immediately afterwards, it sounds like you want FirstOrDefault(), which returns the default value for the element type (which is null for reference types) if no matching items are found:

var documentRow = _dsACL.Documents.FirstOrDefault(o => o.ID == id)

Other options to consider in some situations are Single() (when you believe there's exactly one matching element) and SingleOrDefault() (when you believe there's exactly one or zero matching elements). I suspect that FirstOrDefault is the best option in this particular case, but it's worth knowing about the others anyway.

On the other hand, it looks like you might actually be better off with a join here in the first place. If you didn't care that it would do all matches (rather than just the first) you could use:

var query = from target in _lstAcl.Documents
            join source in _dsAcl.Document
            where source.ID.ToString() equals target.ID
            select new { source, target };
foreach (var pair in query)
{
    target.Read = source.Read;
    target.ReadRule = source.ReadRule;
    // etc
}

That's simpler and more efficient IMO.

Even if you do decide to keep the loop, I have a couple of suggestions:

  • Get rid of the outer if. You don't need it, as if Count is zero the for loop body will never execute
  • Use exclusive upper bounds in for loops - they're more idiomatic in C#:

    for (i = 0; i < _lstAcl.Documents.Count; i++)
    

  • Eliminate common subexpressions:

    var target = _lstAcl.Documents[i];
    // Now use target for the rest of the loop body
    

  • Where possible use foreach instead of for to start with:

    foreach (var target in _lstAcl.Documents)
    

这篇关于序列中没有匹配的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆