我想要更改LINQ查询结果对象的某些属性,而不需要创建一个新对象并手动设置每个属性。这可能吗?
例如:
例如:
var list = from something in someList
select x // but change one property
var list = from something in someList
select x // but change one property
我不确定查询语法是什么。但这里有一个扩展的LINQ表达式示例。
var query = someList.Select(x => { x.SomeProp = "foo"; return x; })
这个方法使用匿名方法而非表达式,其允许你在一个Lambda中使用多个语句。因此,你可以将设置属性和返回对象的两个操作合并到这个比较简洁的方法中。
ToList()
似乎能解决问题。不过我不确定为什么你会收到那个消息。如果是 Entity Framework,则也不能用这种方法。 - Thomas Glaser如果您只想更新所有元素上的属性,则
someList.All(x => { x.SomeProp = "foo"; return true; })
我更喜欢这个。它可以与其他linq命令结合使用。
from item in list
let xyz = item.PropertyToChange = calcValue()
select item
没有任何的 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;
}
Where
子句更新项目,使用.Where(...)将会截断结果,如果您这样做的话:list = list.Where(n => n.Id == ID).Select(n => { n.Property = ""; return n; }).ToList();
您可以像下面这样更新列表中的特定项目:list = list.Select(n => { if (n.Id == ID) { n.Property = ""; } return n; }).ToList();
即使您没有进行任何更改,也请始终返回项目。这样它将保留在列表中。
使用标准查询运算符是不可能的 - 它是语言集成查询,而不是语言集成更新。但你可以在扩展方法中隐藏你的更新操作。
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);
foreach (Item item in this.Items
.Select((x, i) => {
x.ListIndex = i;
x.IsFirst = i == 0;
x.IsLast = i == this.Items.Count-1;
return x;
}))
您可以使用以下方法简单地扩展任何类:
public abstract class IteratorExtender {
public int ListIndex { get; set; }
public bool IsFirst { get; set; }
public bool IsLast { get; set; }
}
public class Item : IteratorExtender {}
在2020年,我使用了MoreLinq
的Pipe
方法。https://morelinq.github.io/2.3/ref/api/html/M_MoreLinq_MoreEnumerable_Pipe__1.htm
由于我在这里没有找到我认为最佳解决方案的答案,因此我要分享我的做法:
使用“Select”来修改数据是可能的,但需要一个技巧。然而,“Select”并不是为此而设计的。只有当与“ToList”一起使用时,“Select”才执行修改操作,因为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);
;
}
}
}
var list = from something in someList;
list.ForEach(x => x.Property = value);