x.UserID =="> x.UserID =="> x.UserID ==" />

избегайте избыточных условных операторов

Используя следующий код, предположите, что у меня есть 5 различных типов, которые я мог бы получить в типе переменной. Вместо того, чтобы писать 5 условных операторов, там способ написать один и использовать переменный "тип", чтобы продиктовать, какова модель, в этом случае "CommentVote?" Или действительно ли это - больше дефицит в способе, которым я проектировал модель данных с каждой из тех 5 вещей, имеющих модель "голосования"?

 if (type == "comment")
 {
      CommentVote voteObj = db.CommentVotes
           .Where(x => x.UserID == UserID && x.CommentID == id)
           .SingleOrDefault();
      if (voteObj != null)
      {
          voteObj.Vote = vote;
          db.SaveChanges();
      }
      else
      {
          CommentVote c = new CommentVote { 
               CommentID = id, UserID = UserID, Vote = vote, DateCreated = DateTime.Now 
          };
          db.CommentVotes.Add(c);
          db.SaveChanges();
      }

      count = (db.CommentVotes.Count(x => x.CommentID == id && x.Vote == true) - db.CommentVotes.Count(x => x.CommentID == id && x.Vote == false));
 }

Magic Code: The stuff I would love to be able to do.

 var modelName = "";
 var modelOtherName = "";
 if (type == "comment") {
      modelName = CommentVote;
      modelOtherName = CommentVotes;
 }

      modelName voteObj = db.modelOtherName
           .Where(x => x.UserID == UserID && x.CommentID == id)
           .SingleOrDefault();

Update: I'm beginning to think my model may be crap based on some of the reading referenced bellow. So I am including some of that as a reference. Let me know if that's the problem I should be trying to solve.

 public class CommentVote
 {
    public int CommentVoteID { get; set; }
    public bool Vote { get; set; }
    public DateTime DateCreated { get; set; }
    public int UserID { get; set; }
    public virtual User User { get; set; } 

    public int CommentID { get; set; }  //This row changes from model to model
    public virtual Comment Comment { get; set; }  //This row changes from model to model
 }

У меня есть горстка моделей, которые почти идентичны.

4
nl ja de
It' s не ясный, что вы хотите изменить. Могли вы писать, что некоторое волшебство изобрело код (даже если это won' t собирают), который показывает что you' d как, в идеальном мире, так, чтобы мы видели что аспект этого кода you' выполнение старающегося избегать ре. Кроме того, как другие типы будут отличаться? Действительно ли код совершенно отличается, главным образом то же самое, почти точно то же самое, точно то же самое, или что?
добавлено автор Servy, источник
Я думаю, что можно искать базовый класс, чтобы определить общую функциональность для того, чтобы экономить, отвергнутый в каждом расширенном объекте ' type'? возможно, используя образец Стола за тип? Как комментарий выше примечаний, нет действительно достаточного количества информации, чтобы предположить то, чего вы пытаетесь достигнуть...
добавлено автор Matthew, источник
Быстрый обзор здесь: blogs.msdn.com/b/alexj/archive/2009/04/15/… Более подробный здесь: weblogs.asp.net/manavi/archive/2010/12/28/…
добавлено автор Matthew, источник
Спасибо за комментарии, I' ve добавил некоторый "волшебный код", я желаю, работал бы. @Matthew, я думаю, что хочу сделать что-то как вы, сказал, но I' m, все еще изучая много этого материала так I' m не совсем уверенный, что все вы сказали предназначенный.
добавлено автор Jed Grant, источник

3 ответы

Поскольку я понимаю вас вопрос, это больше связанной с архитектурой базы данных.

Если подобные голоса не очень отличаются друг от друга (с точки зрения свойств) я, woldn't используют различные столы для них. Вместо этого составьте одну таблицу Голосования с колонкой Типа и (как в примере, который вы обеспечили), nullable колонка для CommentID.

Тогда можно использовать наследование классов, чтобы размышлять голоса (Проголосуйте за базовый класс и дочерний класс CommentedVote).

Стол За Наследование Иерархии в Структуре Предприятия

Update: Best is not to repeat the same propertieses in all classes. You just use inharitence like this:

 public abstract class Vote
 {
    public int VoteID { get; set; }
    public bool isVote { get; set; }
    public DateTime DateCreated { get; set; }
    public int UserID { get; set; }
    public virtual User User { get; set; } 

    public int VoteType { get; set;} //this property specifies type of vote (e.g. VoteType=1 for CommentedVote )
 } 
 public class CommentVote : Vote
 {
    public int CommentID { get; set; }  
    public virtual Comment Comment { get; set; }  
 }
 public class OtherVote : Vote
 {
    public int OtherID { get; set; }  
    public virtual Other Other { get; set; }  
 }

В это очень хорошее сообщение в блоге можно найти весь возможный approches. Тот, о котором я пишу, называют Столом за иерархию (TPH).

2
добавлено
It' s стоящий замечания, что, если вы can' t изменяют данные в основной DB, можно быть в состоянии создать представление в DB или хранимую процедуру, что concats соответствующие колонки каждого из столов вместе в этот логический стол.
добавлено автор Servy, источник
Я могу сделать что-либо, что я хочу к модели данных, у меня может быть очень плохо разработанная модель. Читая ту статью, я don' t понимают много, все I' ve, сделанный до сих пор, был в коде структуры предприятия сначала.
добавлено автор Jed Grant, источник
@semao Говорят, что я использовал TPH, что происходит с моей навигационной недвижимостью в коде EF сначала? Единственное голосование могло принадлежать комментарию, ответу, документ и т.д., мне даже нужна навигационная собственность? Посмотрите обновленный вопрос с образцовым примером.
добавлено автор Jed Grant, источник
Хорошо, я понимаю код выше, но что я don' t понимают, то, что сделать в классе комментария, например, общественном виртуальном ICollection <Голосование>, Голосование создает другую колонку по имени Comment_CommentID вместо того, чтобы использовать тот в классе CommentVote.
добавлено автор Jed Grant, источник

Можно абсолютно уменьшить код до отдельного оператора, предполагающего, что вы выполняете те же самые действия и устанавливаете те же самые данные. В этом случае у вас должен быть интерфейс, который содержит общие действия и данные и фабрику объекта, чтобы иллюстрировать примерами правильный объект на основе типа.

1
добавлено
Уловка обращается с ним таким способом, которым ORM может все еще выполнить вопрос.
добавлено автор Servy, источник
Этот ответ, отвечает на вопрос, в то время как semao помог мне определить основную проблему для тех, которые ищут ответ быть лучше поданным, изучив Шаблон "фабрика".
добавлено автор Jed Grant, источник

Вы могли сделать это, если вы осуществляете Шаблон "фабрика" с отражением, очень простой пример показанный здесь.

Вкратце то, что вы делаете, является этим: Так как у вас есть 5 различных типов, которыми это могло быть, вы сделаете 5 различных классов что каждое орудие определенный интерфейс. Вы тогда создаете фабричный класс, чтобы использовать отражение, чтобы захватить класс, который наиболее подходит для вашей ситуации (быть им с прямым именем класса, как в примере, или с Признаком по классу, такой как здесь). Фабрика возвращает случай того интерфейса, который вы тогда просто призвали бы выставленный метод от интерфейса, чтобы сделать все это для вас.

Большая часть этого - то, что, если бы когда-нибудь необходимо делать другой тип, все, которое необходимо было бы сделать, добавляет другой класс с тем признаком/именем, который вы искали бы на фабрике. Ни один из вашего другого кода не должен был бы быть затронут, таким образом делая вас совместимыми с Открыться/Закрыть Принципом.

0
добавлено
Следует иметь в виду это he' s использование ORM здесь, таким образом, эти вопросы преобразовываются в SQL-запросы, получающие доступ к базе данных, и являются not' t действующий на объекты в памяти. Таким образом что-либо, вы делаете потребности быть чем-то, что поставщик вопроса достаточно умен, чтобы быть в состоянии преобразовать в вопрос базы данных. Отражение doesn' t (обычно) попадают в ту категорию.
добавлено автор Servy, источник
Нет; посмотрите на его желаемый код. Он хочет выполнить тот же самый вопрос LINQ, но только на таблице переменных. В теории у вас мог быть каждый из связанных типов ORM, осуществляют интерфейс, инициализируют IQueryable <thatInterface> и затем выполняют статический вопрос на этом, но мне честно don' t знают, поддержал ли бы ORM его (я знаю некоторых, которые делают, и некоторые это don' t).
добавлено автор Servy, источник
В этом случае, тем не менее, он переместил бы требования базы данных в те классы. I' m предполагающий, что необходимые требования довольно отличались бы от одного типа до другого.
добавлено автор IronMan84, источник
Microsoft Stack Jobs
Microsoft Stack Jobs
1 788 участник(ов)

Work & freelance only Microsoft Stack. Feed https://t.me/Microsoftstackjobsfeed Чат про F#: @Fsharp_chat Чат про C#: @CSharpChat Чат про Xamarin: @xamarin_russia Чат общения:@dotnettalks

Microsoft Developer Community Chat
Microsoft Developer Community Chat
584 участник(ов)

Чат для разработчиков и системных администраторов Microsoft Developer Community. __________ Новостной канал: @msdevru __________ Баним за: оскорбления, мат, рекламу, флуд, флейм, спам, NSFW контент, а также большое количество оффтоп тем. @banofbot