user472269
user472269

Reputation: 367

IEnumerable to List, not returning data

 Public class Class1
    {
       Public int Id {get; set;}
       Public int code {get; set;}
       Public int item1 {get; set;}
       Public int item2 {get; set;}
       Public string data {get; set;}
    }  

    //List filled here
    List<Class1> MyList = GetData();

    int[] codes = {1, 2, 3};       

    IEnumerable<Class1> groupItems = new List<Class1>();

    //Grouping and ordering logic here
    foreach(int code in codes)
    {
        groupItems =   MyList.GroupBy(g => g.Id)
                        .Where(w => w.Any(a => a.Code = code)
                        .Select(s => new 
                                    { key = s.Key, 
                                      items = s.OrderBy(o => o.Item1)
                                               .ThenBy(t => t.Item2)
                                     }
                                )
                                .OrderBy(o => o.Key)
                                .SelectMany(sm => sm.Items);
     }

     MyList.Clear();
     MyList.InsertRange(0, groupItems.ToList());

From the above code output, MyList is empty in the result. What I am doing wrong here?

On the groupItems it is Ienumerable and while adding to MyList. I am converting to List using ToList().

Upvotes: 0

Views: 233

Answers (2)

Ivan Stoev
Ivan Stoev

Reputation: 205929

Fals did a good attempt, but the query just doesn't make sense. The same result could be achieved simply by

var items = from e in MyList where codes.Contains(e.Code)
            orderby e.Id, e.Item1, e.Item2 select e;  

(I usually prefer the lambda syntax, but this is one of the cases when LINQ syntax fits better)

EDIT: But let forget about redundancy and inefficiency of the query and get back to the original issue. Fals already did that in his answer, but seems you missed that part. What is wrong with your code is that you are defining a variable outside of the loop, then inside the loop you just assign a value to the same variable, and finally you use the variable after exiting the loop. Which doesn't make sense because the variable will contain what you have assigned in the last iteration. In your case, even if MyList is not empty, if there are no items with Code == 3, you'll get an empty result. It's similar to writing something like this

var random = new Random();
int result = 1234;
for (int i = 0; i < 3; i++)
    result = random.Next(3);
Console.WriteLine(result);

and asking why it is printing zero sometimes.

Upvotes: 1

Fals
Fals

Reputation: 6839

You should avoid the for, It will always return the last result from groupItems that can be an empty list. Use Contains in code instead.

groupItems =   MyList.GroupBy(g => g.Id)
                        .Where(w => codes.Contains(w.Code))
                        .Select(s => new 
                                    { key = s.Key, 
                                      items = s.OrderBy(o => o.Item1)
                                               .ThenBy(t => t.Item2)
                                     }
                                )
                                .OrderBy(o => o.Key)
                                .SelectMany(sm => sm.Items);

Upvotes: 1

Related Questions