如何处理引用其他存储对象的存储对象?

时间:2016-12-07 04:10:46

标签: c# json azure serialization

考虑使用台球应用程序。您可能需要的一种模型是Match,它引用多个Game对象,每个Game对象包含该游戏的评分数据。当然,MatchGame都会引用Player,因为您需要知道谁在玩。所以考虑到这个相对简单的模型:

class Match
{
    Player Player1;
    Player Player2;
    List<Game> Games;
}

class Game
{
    Player Player1;
    Player Player2;

    // ... scoring data
}

class Player
{
    string PlayerName;
}

我们希望将匹配保存到某个存储(类型不重要,但是,例如,假设我们在Azure中存储了JSON序列化对象的blob)。

我们可以这样做的简单方法是:

storage.SaveBlob(JsonConvert.SerializeObject(myMatch));

但这会保存Player1Player2的多个副本 - 一个用于匹配,一个用于比赛中的每个游戏。

我们可以将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更改其评级级别,例如,我们通常希望更新所有引用(还有情况可能并非如此,但现在暂时忽略。)

目标是在保持一定量的数据规范化的同时进行干净的序列化/反序列化。那么......应该做些什么?这不是常见的问题吗?

1 个答案:

答案 0 :(得分:-2)

对于关系数据库来说这是一个很好的工作。

将实体(匹配,游戏,玩家)存储在不同的表格中。

使用&#34; join&#34;检索它们操作

你提出的建议就是重新发明那种已经存在了几十年的轮子。

另一方面,看起来您正在存储不会发生变化的历史数据,因此非关系型数据库(NoSQL)可能适合您。存储非常便宜,所以不要在这里和那里担心一些重复的数据(因为它不会改变)。

注意:如果您的应用程序可能允许存储的数据发生更改,那么重复的数据就是 evil 并且应该不惜一切代价避免(因此没有人更新一个副本而不更新其他副本),使用关系那种情况下的模型。