【问题标题】:Model relationships about implementing vote system关于实现投票系统的模型关系
【发布时间】:2011-04-30 17:00:13
【问题描述】:

我对投票系统的实施感到困惑。我想知道投票赞成和反对帖子的计数,并保存投票赞成或反对的选民。我使用下面的模型。

public class Post : Entity
{
    public string Title { get; set; }
    public virtual User Owner { get; set; }
    public virtual List<User> UpVoters { get; set; }
    public virtual List<User> DownVoters { get; set; }
}

我觉得这个设计有点问题,因为如果我必须代表一个帖子的投票数和投票数,所以我认为我必须处理 2 个查询。如果我只需要计数,使用导航属性计数会导致性能问题.我说的对吗?

下面的第二种方法也让我感到困惑,因为 VoteUpCount 和 VoteDownCount 应该始终由开发人员手动处理。并且总是在选民改变投票时重新更新值,这看起来有点代码味道。

public class Post : Entity
{
    public string Title { get; set; }
    public virtual User Owner { get; set; }
    public int VoteUpCount { get; set; }
    public int VoteDownCount { get; set; }
    public virtual List<User> UpVoters { get; set; }
    public virtual List<User> DownVoters { get; set; }
}

你能建议我哪个更好吗?为什么更好?我还有其他选择吗?

最后一个帖子保留了 3 个用户导航属性,这让我觉得可能有问题。这段关系有什么问题吗??

【问题讨论】:

    标签: c# .net entity-framework ef-code-first entity-framework-4.1


    【解决方案1】:

    出于本能,我会创建一个 Vote 实体,因为您想保存有关投票的信息:

    public class Vote : Entity
    {
        public User User {get;set;}
        public int VoteDirection {get;set;} // 1 or -1
        // any other info...
    }
    

    然后在 Post 类中添加 Vote 字段:

    public class Post : Entity
    {
        public string Title { get; set; }
        public virtual User Owner { get; set; }
        public virtual List<Vote> Votes { get; set; }
    }
    

    然后你计算每个投票的 VoteDirection 总和......

    【讨论】:

      【解决方案2】:

      我不认为这里有什么问题。

      您的第一个模型在我看来还不错。除非您可以证明获取相关实体的数量会影响性能,否则我不会选择第二个。 过早的优化是万恶之源 ;-)。

      如果您出于性能原因需要存储计数,那么第二个模型也可以。只需确保添加投票会更新计数字段。

      【讨论】:

        【解决方案3】:

        你的第一个模型是正确的,你不应该因为 EF 的缺点而妥协你的模型,第二个版本也不是很好维护 - 涉及太多的思考和手动工作。

        当您想要检索计数时,实际上有一种解决方法可以让 EF 实现所有相关实体,语法不是很直观,但确实会产生正确的 SQL 查询:

        var myPost = context.Posts.First();
        int upvotersCount = context.Entry(myPost)
                                   .Collection(p => p.UpVoters)
                                   .Query()
                                   .Count();
        

        此方法详解here

        此外,作为一般经验法则,您应该在模型中使用 ICollection&lt;User&gt; 而不是具体的 List&lt;User&gt;

        【讨论】:

          【解决方案4】:

          Using navigation properties counts would cause performance problems if i just need counts. Am i right? - 你想到了什么样的性能问题?

          通常,添加计数字段会在您的数据库中引入冗余,但这是一个明显的性能优化步骤。如果我是你,我宁愿问自己在这种情况下是否需要提高性能。数据库中有多少帖子和投票?有多少用户将同时访问这些信息?等等如果您的应用程序需要真正可扩展,您可以添加额外的计数并确保它们正确更新。否则,您可以牢记这种可能性,但不要急于实施。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-01-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-01-08
            • 1970-01-01
            相关资源
            最近更新 更多