【问题标题】:Update List<T> using LINQ使用 LINQ 更新 List<T>
【发布时间】:2016-07-18 13:05:34
【问题描述】:

我有一个列表List&lt;CartLine&gt; linecollection,其中CartLine 是类定义的自定义数据类型

class CartLine
{ 
    public Product {get;set;}
    public Quantity {get;set;}
}

现在我想在我的列表中使用 LINQ 搜索 CartLine line = linecollection.Where(P=&gt;P.Product.ProductId==product.ProductID).FirstOrDefault(),其中小写 product 是传递给方法的参数。现在,如果line 是null,我可以轻松地将项目添加到linecollection。如果不是null,那么我只想将quantity(传递给方法的另一个参数)添加到列表中搜索项的Quantity。

我怎样才能做到这一点?

【问题讨论】:

  • 您的意思是要更新您刚刚从列表中拉出的对象的Quantity 为FirstOrDefault?
  • 您的代码甚至无法编译。 Product和Quantity有哪些类型?
  • 很难猜出你在问什么。如果查询未返回任何项目 (line = null),您想将任何内容添加到列表中,对吗?如果不是null,您要添加quantity?但是由于您的列表是CartLine 类型的列表,您不能添加quantity,而只能添加Cartline-instances。那你到底在问什么?
  • 我想更新该对象的数量,但它也应该在我的列表行集合中更新!
  • 停止在末尾添加带有感叹号的 cmets!这让我们觉得你在生我们的气,因为我们试图帮助你!

标签: c# linq


【解决方案1】:
class Program
    {
        static List<CartLine> linecollection = new List<CartLine>();

        static void Main(string[] args)
        {
            ProductClass product = new ProductClass() { ProductID = 0 };

            linecollection.Add(new CartLine() { Product = product, Quantity = 80 });
            linecollection.Add(new CartLine() { Product = new ProductClass() { ProductID = 1 }, Quantity = 60 });
            linecollection.Add(new CartLine() { Product = new ProductClass() { ProductID = 2 }, Quantity = 40 });

            CartLine line = linecollection.Where(P => P.Product.ProductID == product.ProductID).FirstOrDefault();
            if (line == null)
                linecollection.Add(new CartLine() { Quantity = 100 });
            else
                line.Quantity = 100;
        }
    }

    class CartLine
    {
        public ProductClass Product
        {
            get; set;
        }
        public int Quantity
        {
            get; set;
        }
    }

    class ProductClass
    {
        public int ProductID
        {
            get; set;
        }
    }

您还可以将 LINQ 查询缩短为:

CartLine line = linecollection.Where(P => P.Product == product).FirstOrDefault();

【讨论】:

  • 正如你提到的 line.Quantity=100;以这种方式如何更新 List 中的对象我的意思是 Line 是该对象的另一个副本而不是那个对象?
  • 试一试,你会看到List的item会更新;-)
  • 您从哪里获得ProductClass 和int 的Product 和Quantity 属性类型?我认为你在做假设。在 OP 提供可编译的代码之前,这个问题是无法回答的。
  • 对,我只假设这种结构。但我指责 OP 他将能够使样本适应他的解决方案 ;-)
【解决方案2】:

由于CartLine 是一个类,LINQ 语句返回对实际列表成员的引用。 quantity可以添加如下。

if (line is CartLine)
{
    line.Quantity += quantity;
}

【讨论】:

  • 调用 FirstOrDefault() 时,行始终是 CartLine 类型。
  • 据我了解,FirstOrDefault 将返回 null 作为引用类型,根据 this explanation 和 this question,is 运算符将在 null 上返回 false .
  • 是的,它将返回 null。但这只是价值。 CartLine 是类型。 FirstOrDefault() 参见msdn.microsoft.com/de-de/library/bb340482(v=vs.110).aspx。
  • FirstOrDefault 将始终返回 List 的泛型类型 T,无论它的值是否为 null。
  • @c0d3b34n 你是对的,但是is 运算符在null 上返回false;如果line 设置为null,则表达式line is CartLine 的计算结果为false。
【解决方案3】:

当您查询是否返回一个项目并更新此项目时,列表中的引用也会更新。所以在使用时

CartLine line = linecollection.Where(P => P.Product.ProductId == product.ProductID).FirstOrDefault();
line.Quantity = ...

列表中的项目也会更新,因为它只是引用了您使用查询检索到的相同项目。这是reference-types的基础。您的列表只包含对您的实际对象的引用,因此每当您更新这些对象的任何实例时,这些更改都会反映在所有引用中 - 例如在您的列表中。

您可以通过从列表中重新查询您的项目并获取其数量来检查这一点:

var updatedQuantity = linecollection.Where(P => P.Product.ProductId == product.ProductID).First().Quantity;

现在应该等于您设置的quantitty。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-27
    • 1970-01-01
    • 2020-05-23
    • 1970-01-01
    • 1970-01-01
    • 2021-05-15
    • 2015-07-09
    相关资源
    最近更新 更多