简体   繁体   English

避免冗余条件语句

[英]avoid redundant conditional statements

Using the following code, assume I have 5 different types that I might receive in the variable type. 使用以下代码,假设我有5种不同的类型,我可能会在变量类型中收到。 Instead of writing 5 conditional statements, is there a way to write one and use the variable "type" to dictate what the model is, in this case "CommentVote?" 有没有一种方法可以编写一个并使用变量“type”来决定模型是什么,在这种情况下是“CommentVote?”而不是编写5个条件语句。 Or is this more a deficiency in the way I've designed the data model with each of those 5 things having a "vote" model? 或者这更像是我设计数据模型的方式的缺陷,这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
 }

I have a handful of models that are almost identical. 我有一些几乎相同的模型。

As I understand you question, it more database architecture-related. 据我了解你的问题,它与数据库架构有关。

If those kind of votes are not very different from each other (in terms of properties) I woldn't use different tables for them. 如果这些投票彼此之间没有很大不同(就属性而言),我不会为它们使用不同的表格。 Instead create one Vote table with Type column and (as in the example you provided) nullable column for CommentID. 而是使用Type列创建一个Vote表,并且(如您提供的示例中)为CommentID的可为空列。

Then you can use class inheritance to reflect your votes (Vote base class and CommentedVote child class). 然后,您可以使用类继承来反映您的投票(投票基类和CommentedVote子类)。

Table Per Hierarchy Inheritance in Entity Framework 实体框架中的每层次结构表继承

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; }  
 }

In this very good blog post you can find all possible approches. 这篇非常好的博客文章中,您可以找到所有可能的方法。 The one I'm writing about is called Table per Hierarchy (TPH). 我正在撰写的那个名为Table per Hierarchy(TPH)。

You can absolutely reduce the code to a single statement assuming that you perform the same actions and set the same data. 假设您执行相同的操作并设置相同的数据,您绝对可以将代码减少到单个语句。 In this case, you should have an interface that contains the common actions and data and an object factory to instantiate the correct object based on the type. 在这种情况下,您应该有一个包含公共操作和数据的接口,以及一个根据类型实例化正确对象的对象工厂。

You could do it if you implement the Factory pattern with reflection, a very basic example is shown here . 如果使用反射实现Factory模式,则可以执行此操作, 此处显示了一个非常基本的示例。

In a nutshell what you do is this: Since you have 5 different types that it could be, you would make 5 different classes that each implement a specific interface. 简而言之,你所做的是:由于你有5种不同的类型,你可以创建5个不同的类,每个类都实现一个特定的接口。 You then create the factory class to use reflection to grab the class that is the most appropriate for your situation (be it with a straight-up class name, like in the example, or with an Attribute over the class, such as here ). 然后创建工厂类以使用反射来获取最适合您情况的类(无论是使用直接类名,如示例中,还是使用类上的属性,例如此处 )。 The factory returns an instance of that interface, which you would then just invoke the exposed method from the interface to do all of this for you. 工厂返回该接口的一个实例,然后您可以从接口调用公开的方法来为您完成所有这些操作。

The best part of this is that if you ever need to make another type, all you'd have to do is add another class with that attribute/name that you would be searching for in the factory. 最好的部分是,如果你需要制作另一种类型,你所要做的就是添加另一个具有你将在工厂中搜索的属性/名称的类。 None of your other code would need to be affected, thus making you compliant with the Open/Closed Principle. 您的其他代码都不需要受到影响,从而使您符合开放/封闭原则。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM