Невозможно изменить значение в foreach с IEnumerable <Model> - PullRequest
0 голосов
/ 09 января 2019

Как изменить значение объекта в foreach с IEnumerable<Model>.

Код:

public IEnumerable<Model> ListDaftarPjsp()
{
    IEnumerable<Model> list = from x in db.PJSPEvaluation
                              select new Model
                              {
                                  foo = x.Foo,
                                  bar = x.Bar               
                              };
    foreach (Model item in list) {
        item.condition = "example";
    }
    return list;
}

public class Model{
    public string foo{ get; set; }
    public string bar { get; set; }
    public string condition{ get; set; }
}

Я уже создаю Model. Затем я зацикливаю результат с помощью foreach, затем устанавливаю его. Но Возврат за condition все еще не меняется? как установить условие внутри foreach и вернуть его для результата

Ответы [ 3 ]

0 голосов
/ 09 января 2019

IEnumerable<T> - это запрос, а не коллекция. Хотя на другом конце есть какая-то коллекция, сам запрос не является коллекцией . Характер целевой коллекции будет определять, можете ли вы изменить содержимое.

Общее практическое правило заключается в том, что вы не можете ожидать, что IEnumerable<T> будет возвращать один и тот же список объектов дважды, или даже ожидать, что вы сможете перечислять его несколько раз - это совершенно верно (если необычно) для IEnumerable<T> для перечисления только один раз и отказа от перечисления во второй или третий раз.

В этом случае у вас фактически есть запрос к базе данных типа IQueryable<Model>, который приводится к IEnumerable<Model>. Это по-прежнему IQueryable<Model>, что означает, что каждый раз, когда вы перечисляете его, вы получите (возможно) один и тот же список данных, но в совершенно новых объектах. Изменение одного из объектов не изменит все объекты для одной и той же исходной записи, а также не изменит содержимое самой базовой записи.

Если вы пытаетесь изменить возвращенные объекты без изменения базовых записей (кажется, это так), то вам нужно материализовать запрос в коллекцию в памяти. Есть несколько способов сделать это в зависимости от того, что вы ожидаете сделать с возвращенными данными.

Самое простое - преобразовать запрос в массив, используя метод расширения .ToArray():

public Model[] ListDaftarPjsp()
{
    var query = from x in db.PJSPEvaluation
                select new Model
                {
                    foo = x.Foo,
                    bar = x.Bar               
                };

    var list = query.ToArray();

    foreach (Model item in list) 
    {
        item.condition = "example";
    }

    return list;
}

Теперь записи находятся в массиве в памяти, и перечисление этого массива может быть выполнено несколько раз, возвращая одни и те же точные объекты, вместо того, чтобы каждый раз получать новые копии данных из базы данных.

0 голосов
/ 09 января 2019

Эта тема уже есть, но есть более эффективный способ сделать это. Просто используйте List <> вместо Array [].

  public List<Model> ListDaftarPjsp()
    {
        List<Model> list = from x in db.PJSPEvaluation
                                  select new Model
                                  {
                                      foo = x.Foo,
                                      bar = x.Bar               
                                  };

        foreach (Model item in list) 
        {
            item.condition = "example";
        }
        return list;
    }

    public class Model{
        public string foo{ get; set; }
        public string bar { get; set; }
        public string condition{ get; set; }
    }
0 голосов
/ 09 января 2019

Здесь вы пытаетесь создать список Model, используя LINQ, затем вы повторяете то же самое для добавления дополнительного свойства к каждому элементу. Тогда почему бы вам не добавить свойство во время создания списка вместо дополнительного цикла? Сделайте все просто, попробуйте что-то вроде этого:

from x in db.PJSPEvaluation
select new Model
{
   foo = x.Foo,
   bar = x.Bar,
   condition = GetCondition(x.Foo)              
};

Где GetCondition() может быть определено как:

private string GetCondition(int foo)
{
   if(item.foo == 1) 
   { 
      return "a";
   }
   else if(item.foo == 2) 
   { 
      return "b";
   }
   else
   {
      return "xx";    
   }
}
...