简体   繁体   中英

C# Linq Join Issue

I am trying to join two object list and update the property(Revenue) in the first object (ProductReport) to be the same the one of the properties(Revenue) in the joined object (Transaction). The code is as blow:

using System.Collections.Generic;
using System.Linq;

namespace TestConsole
{
    public class ProductReport
    {
        public string productName { get; set; }
        public int PrdouctID { get; set; }
        public double Revenue { get; set; }
    }

    public class Transaction
    {
        public double Revenue { get; set; }
        public int PrdouctID { get; set; }
    }

    public class Program
    {
        static void Main(string[] args)
        {
            List<ProductReport> products = new List<ProductReport>();
            ProductReport p = new ProductReport();
            p.productName = "Sport Shoe";
            p.PrdouctID = 1;

            products.Add(p);

            List<Transaction> transactions = new List<Transaction>();
            Transaction t1 = new Transaction();
            t1.PrdouctID = 1;
            t1.Revenue = 100.0;

            Transaction t2 = new Transaction();
            t2.PrdouctID = 1;
            t2.Revenue = 200.00;

            transactions.Add(t1);
            transactions.Add(t2);

            var results = (from product in products
                           join transaction in transactions on product.PrdouctID equals transaction.PrdouctID into temp
                           from tran in temp.DefaultIfEmpty()
                           select new { product, tran }
                           ).ToList();

            results.ForEach(x => x.product.Revenue = x.tran.Revenue);
        }

    }
}

The code joins 2 object lists based on ProductID. I am expecting to see two ProductReport items in the results object with 100.00 and 200.00 revenue respectively. However, the foreach function somehow overwrite the revenue property in the first ProductReport. In the end, both ProductReport have 200.00 as the revenue. Can anyone help me with that and how to easily get the result i want ? Thanks.

You'll just need to change your join around

var results = (from p in products
join t in transactions on p.ProductID equals t.ProductId
select new ProductReport{
  ProductName = p.productName,
  ProductId = p.ProductID,
  Revenue = t.Revenue
}).ToList();

You'll then have a list which has 2 entries for ProductId = 1 (Sport Shoe)

ProductName = "Sport Shoe"
ProductId = 1
Revenue = 200.00

ProductName = "Sport Shoe"
ProductId = 1
Revenue = 100.00

The foreach function somehow overwrite the revenue property in the first ProductReport. In the end, both ProductReport have 200.00 as the revenue.

In the following line x.product refers to the same instance.

results.ForEach(x => x.product.Revenue = x.tran.Revenue);

You have only one ProductReport object, and it can have only one value for its Revenue property. The Revenue property of this single instance cannot simultaneously be both 100.00 and 200.00. The first time you write to it, you set it to 100.00 , the second time you write to it, you overwrite it to 200.00 .

I am expecting to see two ProductReport items in the results object.

Your code creates only one ProductReport item. If you want to see two (or more) of them, then you need to create two (or more) objects. The following code leverages Select to do that for you. Whereas your ForEach mutates the original object, Select and the rest of the LINQ create a new object and do not mutate the original one.

var results =
    from product in products
    join transaction in transactions on product.PrdouctID equals transaction.PrdouctID
    select new 
    {
        product, transaction
    };

var updated = results.Select(x => {
    x.product.Revenue = x.transaction.Revenue;
    return x.product;
});

And here it is as a Fiddle with this output:

Sport Shoe 100
Sport Shoe 200

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM