[英]How to automatically convert all Enumerable to List when using Entity Framework?
我的 ASP.NET Core Web API(使用实体框架)中有这个 POST 端点:
[HttpPost]
public async Task<ActionResult<Game>> PostGame(Game game) {
...
game.State = new GameState();
game.State.Map.Rows = game.State.Map.Rows.ToList();
...
}
然后我有这两个类:
public class MapRow {
public int Id { get; set; }
public IEnumerable<MapColumn> Columns { get; set; }
public MapRow() { }
public MapRow(IEnumerable<MapColumn> columns) {
Columns = columns;
}
}
public class Map {
public long Id { get; set; }
public IEnumerable<MapRow> Rows { get; set; }
public Map() { }
public Map(IEnumerable<MapRow> rows) {
Rows = rows;
}
}
其中有两个需要转换为List
或 Entity Framework 的Enumerable
将抛出类似于以下的错误:
System.InvalidOperationException:实体类型“MapRow”上的导航属性“Columns”的类型是“SelectRangeIterator”,它没有实现 ICollection。 集合导航属性必须实现目标类型的 ICollection<>。
我通过在端点本身中调用.ToList()
为我的Rows
解决了这个错误。 然而,由于存在多个端点,你可以有Enumerable
被相当嵌套它迅速成为不可维护不必每次将S Enumerable
到一个List
手动。
有没有更简单的方法可以让我自动化?
对于 EF 实体,集合的导航属性应声明为ICollection<T>
而不是IEnumerable<T>
。 所以例如:
public class MapRow {
public int Id { get; set; }
public virtual ICollection<MapColumn> Columns { get; set; } = new List<MapColumn>();
public MapRow() { }
public MapRow(IEnumerable<MapColumn> columns) {
Columns = columns;
}
}
public class Map {
public long Id { get; set; }
public virtual IColleciton<MapRow> Rows { get; set; } = new List<MapRow>();
public Map() { }
public Map(IEnumerable<MapRow> rows) {
Rows = rows;
}
}
ICollection<T>
扩展了IEnumerable<T>
因此任何需要 IEnumerable 的方法都将完全满足 ICollection。 当您尝试将 IEnumerable 传递给期望 IList 或 ICollection 的内容时,情况就不同了。
将它们声明为virtual
还允许 EF 将代理分配给这些属性,以在需要时协助延迟加载并且 DbContext 仍然可用。 它还有助于将属性自动初始化为新集合,以便在新建 Map 时,您可以立即开始添加行和列,而不会冒NullReferenceException
的风险。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.