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
}
}
我在使用 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
}
}