簡體   English   中英

使用實體框架時如何自動將所有 Enumerable 轉換為 List?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM