简体   繁体   English

如何使用LINQ和C#使用列表更新元素

[英]How to update an element with a List using LINQ and C#

I have a list of objects and I'd like to update a particular member variable within one of the objects. 我有一个对象列表,我想更新其中一个对象内的特定成员变量。 I understand LINQ is designed for query and not meant to update lists of immutable data. 我了解LINQ专为查询而设计,并不意味着更新不可变数据列表。 What would be the best way to accomplish this? 做到这一点的最佳方法是什么? I do not need to use LINQ for the solution if it is not most efficient. 如果不是最有效的解决方案,则无需使用LINQ。

Would creating an Update extension method work? 创建Update扩展方法是否行得通? If so how would I go about doing that? 如果是这样,我将如何去做?

EXAMPLE:
(from trade in CrudeBalancedList
 where trade.Date.Month == monthIndex
 select trade).Update(
 trade => trade.Buy += optionQty);

Although linq is not meant to update lists of immutable data, it is very handy for getting the items that you want to update. 尽管linq并不是要更新不可变数据列表,但它对于获取要更新的项目非常方便。 I think for you this would be: 我认为对您来说,这将是:

(from trade in CrudeBalancedList
    where trade.Date.Month == monthIndex
    select trade).ToList().ForEach( trade => trade.Buy += optionQty);

I'm not sure if this is the best way, but will allow you to update an element from the list. 我不确定这是否是最好的方法,但可以让您更新列表中的元素。

The test object: 测试对象:

 public class SomeClass {
        public int Value { get; set; }
        public DateTime Date { get; set; }
    }

The extension method: 扩展方法:

public static class Extension {
        public static void Update<T>(this T item, Action<T> updateAction) {
            updateAction(item);
        }
    }

The test: 考试:

public void Test()
{
    // test data
    List<SomeClass> list = new List<SomeClass>()
    {
        new SomeClass {Value = 1, Date = DateTime.Now.AddDays(-1)},
        new SomeClass {Value = 2, Date = DateTime.Now },
        new SomeClass {Value = 3, Date = DateTime.Now.AddDays(1)}
    };
    // query and update
    (from i in list where i.Date.Day.Equals(DateTime.Now.Day) select i).First().Update(v => v.Value += 5);

    foreach (SomeClass s in list) {
        Console.WriteLine(s.Value);
    }
}

So you're expecting to get a single result here. 因此,您期望在这里得到一个结果。 In that case you might consider utilizing the SingleOrDefault method: 在这种情况下,您可以考虑利用SingleOrDefault方法:

var record =
    (from trade in CrudeBalancedList
    where trade.Date.Month == monthIndex
    select trade).SingleOrDefault();

if (record != null)
    record.Buy += optionQty;

Note that the SingleOrDefault method expects there to be exactly one or zero value returned (much like a row in a table for some unique primary key). 请注意, SingleOrDefault方法期望返回的值恰好是一个或零 (非常类似于表中某些唯一主键的行)。 If more than one record is returned, the method will throw an exception. 如果返回多个记录,则该方法将引发异常。

To create such a method, you would start with its prototype: 要创建这样的方法,您将从其原型开始:

public static class UpdateEx {
    public void Update(this IEnumerable<T> items, 
                       Expression<Action> updateAction) {
    }
}

That's the easy part. 那是容易的部分。

The hard part will be to compile the Expression<Action> into an SQL update statement. 困难的部分是将Expression<Action> 编译成SQL更新语句。 Depending on how much syntax you want to support, such a compiler's complexity can range from trivial to impossible. 根据要支持的语法的多少,这种编译器的复杂性可能从微不足道到不可能。

For an example of compiling Linq Expressions, see the TableQuery class of the sqlite-net project . 有关编译Linq表达式的示例,请参见sqlite-net项目TableQuery类。

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

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