Dawid Sibiński
Dawid Sibiński

Reputation: 1717

C# - linq join select - operating on original selected objects

In my C# .NET application I have two objects: Article, which is some defined article with its overall price (meaning the price which should be calculated by multiplying the article's price by the quantity of articles ordered) and ArticleOrdered which contains quantity of articles ordered and that article's price. I have the collections of both: collection of articles, which is the collection of ALL articles in the database and collection of only ordered articles. What I now have to do is for each article which is ordered calculate it's overall price by multiplying single article's price by quantity ordered. For that I decided to use linq statement, which selects the common part (using join of course) of both lists (all articles list and ordered articles list). The thing now is that I have to perform some actions (calculating the final price) on the original objects of type Article using fields from orderedArticles. Now I do everything that (very bad ;) ) way:

       var commonArticles = from art in articlesList
            join orderedArt in orderedArticlesList on art.Id equals orderedArt.Id
            select art;

        var commonOrderedArticles = from art in articlesList
            join orderedArt in orderedArticlesList on art.Id equals orderedArt.Id
            select orderedArt;

        foreach (var art in commonArticles)
        {
            foreach (var orderedArt in commonOrderedArticles)
            {
                if (art.Id == orderedArt.Id)
                {
                    art.Price += orderedArt.QuantityOrdered*orderedArt.Price;
                }
            }

        }

...because it gives me the ability to work on Articles' references. The only difference between both linq statements is that in the first statement I select art, and in the second orderedArt. How to make these two linq statements one and perform calculations on original Article's objects properly? I thought about selecting some anonymous type using new keyword there, but as far as I know that will return the completely new type, so working on art.Price I would not work on the reference (original) object, but on the copy. That is also why I now have to perform these strange foreach loops and check if corresponding Id's are the same.

Thank you for any help!

Upvotes: 0

Views: 357

Answers (1)

Alex
Alex

Reputation: 13224

If the orderedArticlesList does not contain multiple entries for an article (i.e. the same Id does not occur twice in the list), you can do:

var orderedArticalTotals =
    from ordered in orderedArticlesList 
    from article in articlesList
    where article.Id == ordered.Id
    select new {
        Article = article,
        OrderTotals = ordered.QuantityOrdered * ordered.Price
    }

foreach (var total in orderedArticalTotals) 
    total.Article.Price += total.OrderTotals;

If there could be multiple entries for the same article in the orderedArticlesList:

var orderedArticalTotals =
    from ordered in orderedArticlesList 
    group ordered by ordered.Id into g
    select new {
        Article = articlesList.Single(a => a.Id == g.Id),
        OrderTotals = g.Sum(o => o.QuantityOrdered * o.Price)
    }

And do the update in the same way:

foreach (var total in orderedArticalTotals) 
    total.Article.Price += total.OrderTotals;

Upvotes: 1

Related Questions