【问题标题】:Looping through (IEnumerable) results and updating, but nothing updated?循环(IEnumerable)结果并更新,但没有更新?
【发布时间】:2011-12-01 22:38:24
【问题描述】:

我正在遍历父记录(“欧洲”)并使用其子记录更新其名为“childPublication”的<Ienumerable> 字段。但是 childPublication 在循环和赋值之后是 null 吗?

这是我的代码:

foreach (var e in europe)
{
    string child = e.HasChild ?? "";
    if (child.Contains("True"))
    {
        IEnumerable<Publication> eChildrens = children.OfType<Publication>()
                                                .Where(ep => ep.ParentID.Equals(e.PublicationId));

        if (eChildrens.Count() > 0)
        {
            e.ChildPublication = eChildrens;
        }
    }
}              

member.EuropeMiddleEastAfricaPublication = europe;

public class Publication
{
    public int PublicationId { get; set; }
    public int ContentTypeId { get; set; }
    public string PublicationName { get; set; }
    public string PublicationFullName { get; set; }
    public string ShortDescription { get; set; }
    public string LongDescription { get; set; }
    public string URL { get; set; }
    public string CountryId { get; set; }
    public string LanguageId { get; set; }
    public string Active { get; set; }
    public string Subscription { get; set; }
    public string ClientOnly { get; set; }
    public string PrintVersion { get; set; }
    public string EmailVersion { get; set; }
    public string RegisteredforPrint { get; set; }
    public string RegisteredforEmail { get; set; }
    public int ParentID { get; set; }
    public string HasChild { get; set; }
    public IEnumerable<Publication> ChildPublication { get; set; }
}

【问题讨论】:

  • 您确认您至少在分配 childPublication 的代码中结束了吗?

标签: c# linq foreach


【解决方案1】:

首先,你有eChildren = children,所以我假设孩子在某个地方被传递?

我可能会这样编码:

foreach (var e in europe) 
{ 
  // .Net 4.0 use: string.IsNullOrWhiteSpace()
  if (!string.IsNullOrEmpty(e.HadChild)
         // I prefer IndexOf which allows Culture and IgnoreCase 
      && e.HasChild.IndexOf("True", StringComparison.CurrentCultureIgnoreCase))
  { 
    IEnumerable<Publication> eChildrens = 
      children.OfType<Publication>()
              .Where(ep => ep.ParentID.Equals(e.PublicationId))
              .ToList();  //Force the IEnumeration to Enumerate.

    if (eChildrens.Count() > 0) 
    { 
      e.ChildPublication = eChildrens; 
    } 
  } 
}    

【讨论】:

    【解决方案2】:

    您应该调试您的程序并确认您确实进入了您的if 并设置了属性。如果你不是,那么它绝对是空的。但是请注意,通过关闭循环变量,无论如何您都在做一些危险的事情。

    IEnumerable<Publication> eChildrens = 
      children.OfType<Publication>().Where(ep =>  
                                             ep.ParentID.Equals(e.PublicationId)); 
    
    if (eChildrens.Count() > 0) 
    { 
         e.ChildPublication = eChildrens; 
    } 
    

    eChildrens 是一个惰性求值查询,它正在捕获循环变量e。当您超出查询范围并尝试使用结果时,除非您有奇怪的期望,否则您的代码不会做您想做的事情。在闭包中,捕获的是 variable,因此当您离开循环时,您的查询将始终查看 same var e。您将有很多对象查看错误的ChildPublication 序列。

    为避免此问题,请在循环内创建一个局部临时变量并关闭该变量

    var temp = e; // local temporary variable, used below
    IEnumerable<Publication> eChildrens = 
      children.OfType<Publication>().Where(ep =>  
                                             ep.ParentID.Equals(temp.PublicationId)); 
    
    if (eChildrens.Count() > 0) 
    { 
      e.ChildPublication = eChildrens; 
    } 
    

    或者通过调用诸如ToList();之类的方法来强制评估查询

    IEnumerable<Publication> eChildrens = 
      children.OfType<Publication>().Where(ep =>  
                                             ep.ParentID.Equals(e.PublicationId)).ToList(); 
    
    if (eChildrens.Count() > 0) 
    { 
      e.ChildPublication = eChildrens; 
    } 
    

    有关此主题的更多信息,请阅读 Eric Lippert 的 blog entry

    【讨论】:

    • 感谢您的洞察力,使用列表所需的问题。
    【解决方案3】:

    这就是问题所在。 IEnumerable 用户是针对您的数据源运行的迭代器。迭代器返回一个新对象,而不是对原始对象的引用。

    因此,您正在对原始数据的副本进行更改,而不是您的实际数据。如果您想修改原始数据,则需要传递对它的引用并使用该引用。

    【讨论】:

      【解决方案4】:

      您是否尝试过使用List&lt;Publication&gt;IEnumerable&lt;Publication&gt;。对于简单的收集处理,我总是有更多的成功。 IEnumerable 经常需要定义一个 Enumerator,这会带来更多开销。

      【讨论】:

      • 什么开销?你知道 List 有 IEnumerable (以及其他)作为基本接口,因此也有一个枚举器?
      猜你喜欢
      • 2015-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多