Цикл (IEnumerable) результатов и обновлений, но ничего не обновляется? - PullRequest
0 голосов
/ 02 декабря 2011

Я перебираю родительские записи ("европа") и обновляю поле <Ienumerable> с именем " childPublication " своими дочерними записями.Но childPublication является нулевым после цикла и присваивания?

Вот мой код:

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; }
}

Ответы [ 4 ]

1 голос
/ 02 декабря 2011

Во-первых, у вас есть 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; 
    } 
  } 
}    
0 голосов
/ 25 июня 2013

Вот проблема.IEnumerable пользователи итератор работают с вашим источником данных.Итераторы возвращают новый объект, а не ссылку на исходный объект.

Итак, вы вносите изменения в копию исходных данных, а не фактических данных.Если вы хотите изменить исходные данные, вам нужно передать ссылку на них и поработать с этой ссылкой.

0 голосов
/ 02 декабря 2011

Вы должны отладить вашу программу и убедиться, что вы на самом деле попадаете внутрь if и устанавливаете свойство.Если нет, то это будет абсолютно нулевым.Но учтите, что вы все равно делаете что-то опасное, закрывая переменную цикла.

IEnumerable<Publication> eChildrens = 
  children.OfType<Publication>().Where(ep =>  
                                         ep.ParentID.Equals(e.PublicationId)); 

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

eChildrens - это лениво вычисленный запрос, который захватывает переменную цикла e.Когда вы выходите за пределы запроса и пытаетесь использовать результаты, если у вас нет странных ожиданий, ваш код не будет выполнять то, что вы хотите.В заключение, это переменная , которая захватывается, поэтому ваш запрос всегда будет смотреть на тот же 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; 
} 

. Подробнее об этой теме читайте в записи в блоге Эрика Липперта .

.
0 голосов
/ 02 декабря 2011

Вы пытались использовать List<Publication> вместо IEnumerable<Publication>.У меня всегда есть куда больше успеха для простой обработки коллекций.IEnumerable часто хочет, чтобы был определен Enumerator, что немного больше затрат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...