我想改变一个LINQ查询结果对象的一些属性,而不需要创建一个新的对象和手动设置每个属性。这可能吗?

例子:

var list = from something in someList
           select x // but change one property

当前回答

不应该有任何LINQ魔法阻止你这样做。不要使用投影,那会返回一个匿名类型。

User u = UserCollection.FirstOrDefault(u => u.Id == 1);
u.FirstName = "Bob"

这将修改真实对象,以及:

foreach (User u in UserCollection.Where(u => u.Id > 10)
{
    u.Property = SomeValue;
}

其他回答

由于我在这里没有找到我认为最好的解决方案的答案,下面是我的方法:

使用“选择”来修改数据是可能的,但只是有一个技巧。总之,"选择"不是为这个设计的。它只在与“ToList”一起使用时执行修改,因为Linq在需要数据之前不会执行。 无论如何,最好的解决方案是使用“foreach”。在下面的代码中,你可以看到:

    class Person
    {
        public int Age;
    }

    class Program
    {
        private static void Main(string[] args)
        {
            var persons = new List<Person>(new[] {new Person {Age = 20}, new Person {Age = 22}});
            PrintPersons(persons);

            //this doesn't work:
            persons.Select(p =>
            {
                p.Age++;
                return p;
            });
            PrintPersons(persons);

            //with "ToList" it works
            persons.Select(p =>
            {
                p.Age++;
                return p;
            }).ToList();
            PrintPersons(persons);

            //This is the best solution
            persons.ForEach(p =>
            {
                p.Age++;
            });
            PrintPersons(persons);
            Console.ReadLine();
        }

        private static void PrintPersons(List<Person> persons)
        {
            Console.WriteLine("================");
            foreach (var person in persons)
            {
                Console.WriteLine("Age: {0}", person.Age);
            ;
            }
        }
    }

在"foreach"之前,你也可以做一个linq选择…

我不确定查询语法是什么。下面是扩展的LINQ表达式示例。

var query = someList.Select(x => { x.SomeProp = "foo"; return x; })

它所做的是使用匿名方法vs和表达式。这允许您在一个lambda中使用多个语句。因此,您可以将设置属性和返回对象这两个操作结合到这个稍微简洁的方法中。

这对于标准查询操作符是不可能的——它是语言集成查询,而不是语言集成更新。但是您可以将更新隐藏在扩展方法中。

public static class UpdateExtension
{
    public static IEnumerable<Car> ChangeColorTo(
       this IEnumerable<Car> cars, Color color)
    {
       foreach (Car car in cars)
       {
          car.Color = color;
          yield return car;
       }
    }
}

现在您可以像下面这样使用它。

cars.Where(car => car.Color == Color.Blue).ChangeColorTo(Color.Red);

如果你只是想更新所有元素的属性,那么

someList.All(x => { x.SomeProp = "foo"; return true; })

我遇到了确切的要求(OP的问题),我没有看到在任何地方用表达来回答。

假设x是MyType类型,您可以调用一个返回MyType的方法,该方法接受x。在该方法中,您可以做所有您想做的修改。代码看起来像这样。

var list = from something in someList
           select GetModifiedObject(x); // but change one property

private MyType GetModifiedObject(MyType x)
{
   x.Property1 = "Changed Value";
   return x;
}