IEnumerable <t>不反映元素的变化

时间:2018-02-26 15:19:23

标签: c# .net-core ienumerable

我遇到了IEnumerable的麻烦。来自EF Core DbContext的_entities是IQueryable。 _result是IEnumerable。

此代码不起作用; _result仍然未分类。

var _result = _entities.Select(s => this.IMapper.Map<Models.role, DTO.role>(s));

foreach (var _role in _result)
{
    _role.permissions = _role.permissions.OrderBy(o => o.module).ThenBy(o => o.feature).ToArray();
}

return _result;

此代码确实有效; _result已排序。

var _result = _entities.Select(s => this.IMapper.Map<Models.role, DTO.role>(s)).ToArray();

foreach (var _role in _result)
{
    _role.permissions = _role.permissions.OrderBy(o => o.module).ThenBy(o => o.feature).ToArray();
}

return _result;

任何人都可以解释一下吗?

1 个答案:

答案 0 :(得分:0)

原因是LINQ在Select的迭代和IEnumerable的每次迭代中评估IEnumerable

这意味着如果您对从Select返回的项目执行更改,那些对象将被丢弃,并且在下一次迭代中,您将使用原始数据下注新对象。

放置ToArray会导致Select的结果存储在集合中,因此您对对象执行的更改将按预期工作。

为了演示此行为,如果添加一些Console.WriteLine

,则可以看到输出
class Item
{
    public int Value { get; set; }
    static int id = 0;
    public int Id { get; } = id++; // generate next id every time
}
static void Main(string[] args)
{
    var range = new int[] { 1, 2, 3 }
        .Select(i => new Item { Value = i });

    foreach (var item in range)
    {
        Console.WriteLine(item.Value + "- id:" + item.Id);
        // Will output 
        //1- id:0
        //2- id:1
        //3- id:2
    }
    foreach (var item in range)
    {
        Console.WriteLine(item.Value + "- id:" + item.Id);
        // Will output 
        //1- id:3
        //2- id:4
        //3- id:5
    }
}