首页 文章

LINQ:选择一个对象并在不创建新对象的情况下更改某些属性

提问于
浏览
175

使用LINQ,如果我想执行一些查询并从查询返回对象,但只更改该对象中的某些属性,如何在不创建新对象的情况下执行此操作并手动设置每个属性?这可能吗?

例:

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

10 回答

  • 26

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

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

    我更喜欢这个 . 它可以与其他linq命令结合使用 .

    from item in list
    let xyz = item.PropertyToChange = calcValue()
    select item
    
  • 0

    我不确定查询语法是什么 . 但这是扩展的LINQ表达式示例 .

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

    这样做是使用匿名方法vs和表达式 . 这允许您在一个lambda中使用多个语句 . 因此,您可以组合设置属性的两个操作,并将对象返回到这个有点简洁的方法中 .

  • 0

    应该没有任何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;
    }
    
  • 0

    标准查询运算符是不可能的 - 它是语言集成查询,而不是语言集成更新 . 但您可以在扩展方法中隐藏更新 .

    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);
    
  • 0
    var item = (from something in someList
           select x).firstordefault();
    

    得到该项目,然后你可以做item.prop1 = 5;改变具体的 property .

    或者,您是否希望从数据库中获取项目列表,并将其返回列表中每个项目的属性prop1更改为指定值?如果是这样你可以做到这一点(我在VB中这样做因为我知道它更好):

    dim list = from something in someList select x
    for each item in list
        item.prop1=5
    next
    

    (列表将包含随更改返回的所有项目)

  • 53

    既然我在这里找不到答案,我认为这是最好的解决方案,我的方式是:

    使用“选择”来修改数据是可能的,但只需要一个技巧 . 无论如何,“选择”不是为此而做的 . 它只是在与“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 ...

  • 9

    如果要使用 Where 子句更新项目,则使用.Where(...)将截断结果:

    mylist = mylist.Where(n => n.Id == ID).Select(n => { n.Property = ""; return n; }).ToList();
    

    您可以对列表中的特定项目进行更新,如下所示:

    mylist = mylist.Select(n => { if (n.Id == ID) { n.Property = ""; } return n; }).ToList();
    

    即使您不做任何更改,也始终返回项目 . 这样它将保留在列表中 .

  • -3

    我们经常遇到这种情况,我们希望在列表中包含索引值以及第一个和最后一个指示符,而不创建新对象 . 这允许您知道列表中项目的位置,枚举等,而无需修改现有类,然后知道您是在列表中的第一项还是最后一项 .

    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 {}
    
  • 17
    User u = UserCollection.Single(u => u.Id == 1);
    u.FirstName = "Bob"
    

相关问题