Search code examples
c#listlinqumbraco

how to iterate with Linq to create list of objets?


I'm trying to iterate from a list with Linq in order to create and return a model, with contains a list of item and a quantity of total items.

The object that must be returned is as following:

public class ListeArticlesModel
    {        
        public List<TuileArticleModel> Items { get; set; }

        public int Quantity { get; set; }

    }

I'm currently stuck with this :

result.Actualites = tousLesArticlesFromDb
                .ToList()
                .Where(
                    a => a.GetPropertyValue<IEnumerable<IPublishedContent>>("ficheArticle_typeDeContenu")
                             .FirstOrDefault()?.Name == @EnumResources.TypeDeContenu_Actualites)
                .OrderBy(a => a.CreateDate)
                .Take(criteriaModel.NbrItemsParPage)
                .Select(
                    a => new ListeArticlesModel
                    {
                        Items = new List<TuileArticleModel>
                        {
                            // returns a TuileArticleModel 
                            getItem(a)
                        },
                    })
                .FirstOrDefault();

This is not what I want. If I remove the .FirstOrDefault() I get an IEnumerable

I know I am missing something. I'm building a new ListeArticleModel for each "a" item and then I just take the first one built but I don't see how to get out of here...

(ps : I graduated a few weeks ago. I am new to C#. I know it may be basics. I am trying to learn them :D)

I tried this:

var actus = tousLesArticlesFromDb
                    .ToList()
                    .Where(
                        a => a.GetPropertyValue<IEnumerable<IPublishedContent>>("ficheArticle_typeDeContenu")
                                 .FirstOrDefault()?.Name == @EnumResources.TypeDeContenu_Actualites)
                    .OrderBy(a => a.CreateDate)
                    .Take(criteriaModel.NbrItemsParPage);

This gives me an IEnumerable (using umbraco here) which contains the criteriaModel.NbrItemsParPage IPublishedContent items of type "Actualites" that I want...

Now, for each I'd like to create a new TuileArticleModel to feed the Items proptery (a List<TuileArticleModel>) of my result.Actualites...

EDIT :

I think I just resolved my problem by exposing it to you guys, and reading the comments. So I did this :

 var actus = tousLesArticlesFromDb
                    .ToList()
                    .Where(
                        a => a.GetPropertyValue<IEnumerable<IPublishedContent>>("ficheArticle_typeDeContenu")
                                 .FirstOrDefault()?.Name == @EnumResources.TypeDeContenu_Actualites)
                    .Take(criteriaModel.NbrItemsParPage);

                result.Actualites.Items = actus.Select(a => {return getItem(a); }).ToList();

or in one statement :

  result.Actualites = new ListeArticlesModel
                {
                    Items = tousLesArticlesFromDb
                            .Where
                            (
                                a => a.GetPropertyValue<IEnumerable<IPublishedContent>>("ficheArticle_typeDeContenu")
                                         .FirstOrDefault()?.Name == @EnumResources.TypeDeContenu_Actualites
                            )
                            .OrderBy(a => a.CreateDate)
                            .Take(criteriaModel.NbrItemsParPage)
                            .Select(a => { return getItem(a); }).ToList(),
                };

Solution

  • Get the resultset first:

    var results = tousLesArticlesFromDb
        .Where
        (
            a => a.GetPropertyValue<IEnumerable<IPublishedContent>>("ficheArticle_typeDeContenu")
                  .FirstOrDefault()?.Name == @EnumResources.TypeDeContenu_Actualites
        )
        .OrderBy(a => a.CreateDate)
        .Take(criteriaModel.NbrItemsParPage);
    

    Then pass it into the new object:

    result.Actualites = new ListeArticlesModel
        {
            Items = results.ToList()
        };
    

    Or, if you want to do it all in one statement:

    result.Actualites = new ListeArticlesModel
    {
        Items = tousLesArticlesFromDb
            .Where
            (
                a => a.GetPropertyValue<IEnumerable<IPublishedContent>>("ficheArticle_typeDeContenu")
                      .FirstOrDefault()?.Name == @EnumResources.TypeDeContenu_Actualites
            )
            .OrderBy(a => a.CreateDate)
            .Take(criteriaModel.NbrItemsParPage);
            .ToList()
    };