我想更改LINQ查询结果对象的某些属性,而无需创建新对象并手动设置每个属性。这可能吗?
例:
var list = from something in someList
select x // but change one property
我想更改LINQ查询结果对象的某些属性,而无需创建新对象并手动设置每个属性。这可能吗?
例:
var list = from something in someList
select x // but change one property
Answers:
我不确定查询语法是什么。但是,这是扩展的LINQ表达式示例。
var query = someList.Select(x => { x.SomeProp = "foo"; return x; })
这样做是使用匿名方法vs和表达式。这使您可以在一个lambda中使用多个语句。因此,您可以将设置属性和将对象返回到此简洁方法中的两种操作结合在一起。
ToList()
之前添加一个似乎可以解决问题。不知道为什么你得到了。如果它是实体框架,那么它也不起作用。
如果只想更新所有元素上的属性,则
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;
}
使用标准查询运算符是不可能的-它是Language Integrated Query,不是Language Integrated Update。但是您可以在扩展方法中隐藏更新。
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);
UPDATE
,DELETE
和INSERT
。因此,我不会认为语义是阻止此功能的原因。
我们经常遇到这种情况,我们希望在列表中包括索引值以及第一个和最后一个指示符,而无需创建新对象。这使您无需修改现有的类即可知道项目在列表中的位置,枚举等,然后知道您是列表中的第一项还是最后一项。
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 {}
由于我在这里找不到最佳解决方案的答案,因此按以下方式操作:
使用“选择”修改数据是可能的,但这只是一个技巧。无论如何,并非为此选择“选择”。与“ 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选择...
var item = (from something in someList
select x).firstordefault();
将获得item
,然后您可以item.prop1=5;
更改特定的属性。
还是要从数据库中获取项目列表,并让其将prop1
返回列表中每个项目的属性更改为指定值?如果是这样,您可以这样做(我在VB中这样做是因为我更了解它):
dim list = from something in someList select x
for each item in list
item.prop1=5
next
(list
将包含您所做更改返回的所有项目)
for each
循环。
在2020年,我使用该MoreLinq
Pipe
方法。 https://morelinq.github.io/2.3/ref/api/html/M_MoreLinq_MoreEnumerable_Pipe__1.htm