Типовые отношения по внедрению системы голосования - PullRequest
0 голосов
/ 30 апреля 2011

Я запутался по поводу внедрения системы голосования. Я хочу знать, голосовать за и против подсчета постов, а также спасать избирателей, которые проголосовали за или против. Я использую модель ниже.

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 свойства навигации пользователя, и это заставляет меня чувствовать, что что-то может быть не так. Что-то не так в этих отношениях ??

Ответы [ 4 ]

2 голосов
/ 30 апреля 2011

Инстинктивно, я бы создал объект голосования, так как вы хотите сохранить информацию о голосах:

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

Затем добавьте поле Голосовать в классе сообщений:

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

Затем выподсчитать сумму голосования по каждому голосу ...

1 голос
/ 30 апреля 2011

Using navigation properties counts would cause performance problems if i just need counts. Am i right? - какие проблемы с производительностью вы имеете в виду?

Как правило, добавление полей подсчета привносит избыточность в вашу базу данных, но является очевидным шагом оптимизации производительности. Если бы я был тобой, я бы лучше спросил себя, нужно ли мне улучшить производительность в этом случае. Сколько постов и голосов будет в базе данных? Сколько пользователей собираются получить доступ к этой информации одновременно? И т. Д. Если ваше приложение должно быть действительно масштабируемым, вы можете добавить дополнительные значения и убедиться, что они обновлены правильно. В противном случае вы можете просто помнить об этой возможности, но не спешите ее реализовывать.

1 голос
/ 30 апреля 2011

Ваша первая модель - правильная, вы не должны ставить под угрозу свою модель из-за недостатков EF, а вторая версия не очень удобна в обслуживании - слишком много мышления и ручных усилий.

На самом деле есть обходной путь для EF, материализующий все связанные сущности, когда вы хотите получить счетчик, синтаксис не очень интуитивен, но приводит к правильному запросу SQL:

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

Этот подход детализирован здесь .

Также в качестве общего практического правила вы должны использовать ICollection<User> вместо конкретного List<User> в вашей модели.

1 голос
/ 30 апреля 2011

Я не думаю, что здесь что-то не так.

Ваша первая модель выглядит неплохо для меня.Я не пошел бы на второй, если вы не можете доказать, что есть снижение производительности для получения количества связанных объектов. Преждевременная оптимизация - корень всех зол ; -).

Если вам нужно сохранить счет по соображениям производительности, то вторая модель тоже подойдет.Просто убедитесь, что добавление голосования обновляет поле счета.

...