我对投票系统的实施感到困惑。我想知道投票和投票减少邮政的数量,并挽救投票上涨或下跌的选民。我使用下面的模型。
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; }
}
你能告诉我哪个更好吗?为什么更好?我还有其他选择吗?
Lastyly帖子中有3个用户导航属性,这让我觉得有些事情可能有问题。这种关系有什么不妥吗?
答案 0 :(得分:2)
本能地,我会创建一个投票实体,因为你想要保存投票信息:
public class Vote : Entity
{
public User User {get;set;}
public int VoteDirection {get;set;} // 1 or -1
// any other info...
}
然后在Post类中添加投票字段:
public class Post : Entity
{
public string Title { get; set; }
public virtual User Owner { get; set; }
public virtual List<Vote> Votes { get; set; }
}
然后你计算每个投票的VoteDirection的总和......
答案 1 :(得分:1)
我认为这里没有任何错误。
你的第一个模型看起来很不错。我不会选择第二个,除非你能证明在获得相关实体数量方面存在性能损失。 过早优化是万恶之源; - )。
如果由于性能原因需要存储计数,那么第二个模型也可以。只需确保添加投票即可更新计数字段。
答案 2 :(得分:1)
你的第一个模型是正确的,你不应该为了EF的缺点而牺牲你的模型,第二个版本也不是很容易维护 - 有太多的思考和手动工作。
当您想要检索计数时,实际上有一种解决方法可以实现所有相关实体的EF,语法不是非常直观,但会产生正确的SQL查询:
var myPost = context.Posts.First();
int upvotersCount = context.Entry(myPost)
.Collection(p => p.UpVoters)
.Query()
.Count();
此方法详细here。
另外,作为一般经验法则,您应该使用ICollection<User>
而不是模型中的具体List<User>
。
答案 3 :(得分:1)
Using navigation properties counts would cause performance problems if i just need counts. Am i right?
- 您有什么样的性能问题?
通常,添加计数字段会在数据库中引入冗余,但这是一个明显的性能优化步骤。如果我是你,我宁愿问自己在这种情况下是否需要提高性能。数据库中会有多少帖子和投票?有多少用户同时访问此信息?等等。如果您的应用程序需要真正可扩展,您可以添加额外的计数并确保它们正确更新。否则,你可以记住这种可能性,但不要急于实现它。