考虑一个台球应用程序。您可能需要的一种模型是Match
,其中引用了多个Game
对象,其中每个对象都包含该游戏的评分数据。当然,Match
和Game
参考Player
,因为你需要知道谁在玩。因此,鉴于这种相对简单的模型:如何处理引用其他存储对象的存储对象?
class Match
{
Player Player1;
Player Player2;
List<Game> Games;
}
class Game
{
Player Player1;
Player Player2;
// ... scoring data
}
class Player
{
string PlayerName;
}
我们希望我们的比赛保存到一些存储(类型是不重要的,但例如,可以说我们存储JSON序列化对象的斑点在Azure中)。
最简单的方法,我们可以做到这一点是:
storage.SaveBlob(JsonConvert.SerializeObject(myMatch));
但是,这将节省的Player1
和Player2
多个副本 - 一个用于比赛和一个在一场比赛每场比赛。
我们可以改变Game
到:
class Game
{
[JsonIgnore]
Player Player1;
[JsonIgnore]
Player Player2;
// ... scoring data
}
这解决了我们的重复播放器的问题,但现在我们有一个反序列化将需要Match
来解决所有的引用Game
对象的数据成员的问题,与任何一起其他类似的对象在更复杂的情况下。
我们可以再次更新Game
:
class Game
{
[JsonIgnore]
Match Match;
[JsonIgnore]
Player Player1 => Match.Player1;
[JsonIgnore]
Player Player2 => Match.Player2;
// ... scoring data
}
这简化了问题,但仍需要Match
反序列化来解决它的性质。此外,添加这种类型的抽象创建的问题Game
对象必须部分Match
。从概念上讲,情况并非如此(没有理由不可以让Game
不是完整的Match
的一部分),所以这看起来很糟糕。
不同的选项可能会改变Match
到:
class Match
{
Player Player1 => Games.First().Player1;
Player Player2 => Games.First().Player2;
List<Game> Games;
}
这类解决了我们有Player
对象的问题,它保存多个类的,但是会造成数据的重复很大。另外,如果我们将所有这些数据保存到存储中,然后Player
更改它们的评级级别,例如,我们通常希望也更新所有引用(有些情况下可能不是这种情况,但现在让我们忽略)。
目标是在保持一定数量的数据规范化的同时,有干净的序列化/反序列化。所以......应该做什么?这不是一个常见问题吗?
这是一个非常广泛的问题,包含许多可能的答案(包括关系数据库,列数据库,键/值,图表,文档等多种类型的数据存储)以及这些类别中的许多品牌的数据库。 –
你没有错,但有几个正确答案的问题并不错。我很高兴听到任何适合这种情况:) – Rollie