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

IEnumerable<T> does not reflect changes on elements

我在使用 IEnumerable 时遇到问题。 _entities 是来自 EF Core DbContext 的 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;

谁能解释一下?

原因是 LINQ 在 IEnumerable 的迭代和 IEnumerable.

的每次迭代中计算 Select

这意味着如果您对从 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
    }
}