【问题标题】:Navigation property issue导航属性问题
【发布时间】:2019-12-17 19:48:00
【问题描述】:

我在 C# 中创建了一个 ChessLibrary,并在 WinForms 项目上对其进行了测试。

现在,我正在尝试使用 ASP.NET MVC、EF 代码优先创建一个网站来使用这个库。

我在我的 asp.net mvc 项目中创建了一个 Game 模型,具有以下属性:

using ChessLibrary;

namespace ChessWebsite.Models
{
    public class Game
    {
        public int Id { get; set; }
        public ApplicationUser WhitePlayer { get; set; }
        public ApplicationUser BlackPlayer { get; set; }
        public GameBoard GameBoard { get; set; }

    }
}

当我尝试Add-Migration 时,我收到以下错误:

One or more validation errors were detected during model generation:

ChessWebsite.Models.GameBoard: : EntityType 'GameBoard' has no key defined. Define the key for this EntityType.
ChessWebsite.Models.Move: : EntityType 'Move' has no key defined. Define the key for this EntityType.
GameBoards: EntityType: EntitySet 'GameBoards' is based on type 'GameBoard' that has no keys defined.
Moves: EntityType: EntitySet 'Moves' is based on type 'Move' that has no keys defined.

我的GameBoard 类具有以下属性:

public List<Move> Moves { get; set; }
public Piece[,] Board { get; set; }

public GameState GameState { get; private set; }
public bool CanWhiteCastleKingSide { get; private set; } = true;
public bool CanWhiteCastleQueenSide { get; private set; } = true;
public bool CanBlackCastleKingSide { get; private set; } = true;
public bool CanBlackCastleQueenSide { get; private set; } = true;

我不确定是否有简单的解决方案,或者我从一开始就有设计问题?

之前有人问过这个问题,但解决方案是在错误中将[Key] 属性添加到EntityType。但我不需要MoveGameBoard 的密钥。

【问题讨论】:

  • 如果你想存储动作,它们确实需要一个键,它们应该是Game 的集合。那么GameBoard 可能是一个复杂类型。
  • 向我展示如何映射实体之间的关系。此外,Gameboard 实体没有 id。
  • ChessLibrary 项目本身不需要 id,因此假设该库只是一个我无权访问的黑盒。我希望解决方案在 asp mvc 项目中。
  • @Valkyrie,除了mvc中的默认身份,我只有一个DbSet&lt;Game&gt;。 GameBoard 类是库的一部分,我已将此库引用到我的 mvc 项目。正如我在之前的评论中所说,该库不需要 GameBoard 的 Id。另外,每个Game 应该只与一个GameBoard 相关,那么为什么我会有一个GameBoard 的ID?

标签: c# entity-framework ef-code-first entity-framework-migrations code-first


【解决方案1】:

每个游戏应该只与一个 GameBoard 相关,所以为什么我会有一个 GameBoard 的 ID

这是关键问题。在内存中,对象不需要 ID。但是,如果您想将对象保存到数据库并稍后检索它,则它必须具有 key 属性。

您可能应该将游戏状态序列化为 JSON 文档并存储和检索它,而不是将每个类映射到单独的数据库表。在 EF Core 中,您可以使用 Value Conversion 在单个列中以 JSON 格式存储和检索整个 GameBoard。参见例如https://github.com/Innofactor/EfCoreJsonValueConverter,或者只是在某个实体的字符串属性中自己序列化它。

【讨论】:

  • 我没有使用 .NET Core,但 JSON 序列化的想法对我来说似乎不错 :) 谢谢!
  • @david-browne-microsoft 我在序列化中遇到了问题,我的 GameBoard 有一个变量Board,它是Piece 的二维数组。 Piece 是一个抽象类,有从它派生的子类,如 Rook、Bishop 等。所以序列化的字符串没有任何关于实际片段的指示。我可以通过在抽象类中添加:public string PieceName =&gt; this.GetType().Name; 来解决这个问题。但是,以后尝试反序列化时会导致问题吗?有没有更好的方法。
  • 使用var settings = new JsonSerializerSettings { TypeNameHandling = All }; 解决了我在上次评论中的问题。
猜你喜欢
  • 2016-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-27
  • 1970-01-01
相关资源
最近更新 更多