代码之家  ›  专栏  ›  技术社区  ›  Mister 832

使用linq更新值

  •  0
  • Mister 832  · 技术社区  · 8 年前

    我正在尝试更新 Selected 的属性 IEnumerable<SelectListItem> 对于使用linq的MVC组合框网站。但是,这不起作用,如去bug结果所示: Count() 对于条件,返回一个项,但是 计数() 对于 .Selected == true 返回0。

    public IEnumerable<SelectListItem> Categories { get; set; }
    
    public CategoryModel Category
    {
        get { return category; }
        set 
        {
            category = value;
            Categories.Where(x => x.Value == value.Id.ToString()).First().Selected = true;
        }
    
    //Debugging Results
    //?Categories.Where(x => x.Value == value.Id.ToString()).Count()
    //1
    //?Categories.Count(x => x.Selected == true);
    //0
    
    }
    

    更新: 我想这个问题更多地与 IEnumerable<选择列表项(>); ,因为将类别更改为 ObservableCollection 尽管Lin Q 不是为更改数据而设计的。。。。

    System.Diagnostics.Debug.Print(Categories.Where(x => x.Id == value.Id).FirstOrDefault().Description);
    
    Categories.Where(x => x.Id == value.Id).FirstOrDefault().Description = "Stackoverflow";
    
    System.Diagnostics.Debug.Print(Categories.Where(x => x.Id == value.Id).FirstOrDefault().Description);
    
    2 回复  |  直到 8 年前
        1
  •  4
  •   Tim Schmelter    8 年前

    Q 是查询数据源而不是修改它。

    无论如何,您当前的方法有一个缺点,您可以选择一个,但不会取消选择其他方法。所以你需要一个循环:

    public CategoryModel Category
    {
        get { return category; }
        set 
        {
            category = value;
            // consider to use a lock here to avoid multi threading issues
            foreach(SelectListItem catItem in Categories)
               catItem.Selected = catItem.Value == value.Id.ToString();
        }
    }
    

    我会用一种方法 SetSelectedCategory 而不是属性,如果我要修改集合。

        2
  •  1
  •   Dan Dohotaru    8 年前

    IEnumerable不能保证更改在枚举中持久化。 这一切最终取决于底层实现(列表、数组、可观察等)。

    您可以选择将实际类别更改为可写集合(如列表)。。。 但您可能无法做到这一点,或者您可能只是希望保持精益并继续使用IEnumerable。 在这种情况下,您可以简单地修改原始集合并将其投影到原始集合上

    void Main()
    {
        Categories = Load();
    
        var active = new Func<CategoryModel, int, CategoryModel>((category, match) =>
        {
            return new CategoryModel
            {
                Id = category.Id,
                Name = category.Name,
                Active = category.Id == match
            };
        });
    
        Categories = Categories.Select(p => active(p, 2));
        Categories.Dump();
    }
    
    public IEnumerable<CategoryModel> Categories { get; set; }
    
    public IEnumerable<CategoryModel> Load()
    {
        yield return new CategoryModel { Id=1, Name = "one" };
        yield return new CategoryModel { Id=2, Name = "two" };
        yield return new CategoryModel { Id=3, Name = "three" };
    }
    
    public class CategoryModel
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public bool Active { get; set; }
    }
    
    
    Id|Name|Active
    1 one False 
    2 two True 
    3 three False 
    

    这也是为了强调,您可以使用linq进行使用“投影”的“转换”