简体   繁体   English

C#Linq加入问题

[英]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). 我试图加入两个对象列表,并更新第一个对象(ProductReport)中的property(Revenue),使其与加入的对象(Transaction)中的property(Revenue)相同。 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. 该代码根据ProductID连接2个对象列表。 I am expecting to see two ProductReport items in the results object with 100.00 and 200.00 revenue respectively. 我希望在结果对象中看到两个ProductReport项,分别具有100.00和200.00的收入。 However, the foreach function somehow overwrite the revenue property in the first ProductReport. 但是,foreach函数以某种方式覆盖了第一个ProductReport中的Revenue属性。 In the end, both ProductReport have 200.00 as the revenue. 最后,两个ProductReport的收入均为200.00。 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) 然后,您将获得一个列表,其中包含2个条目,分别用于ProductId = 1(运动鞋)

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. foreach函数以某种方式覆盖了第一个ProductReport中的Revenue属性。 In the end, both ProductReport have 200.00 as the revenue. 最后,两个ProductReport的收入均为200.00。

In the following line x.product refers to the same instance. 在下面的行中, x.product引用相同的实例。

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. 您只有一个ProductReport对象,并且其Revenue属性只能有一个值。 The Revenue property of this single instance cannot simultaneously be both 100.00 and 200.00. 该单个实例的Revenue属性不能同时为100.00和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 . 第一次写入时,将其设置为100.00 ,第二次写入时,将其覆盖为200.00

I am expecting to see two ProductReport items in the results object. 我期望在结果对象中看到两个ProductReport项目。

Your code creates only one ProductReport item. 您的代码仅创建一个ProductReport项目。 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. 以下代码利用Select为您完成此操作。 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. ForEach更改原始对象,而Select和LINQ的其余部分会创建一个新对象,而不会更改原始对象。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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