2015-04-22 108 views
12

如果我有一個類以某種方式表示映射到我的數據庫中的特定表。 此類包含約30個屬性。如果我想創建多個CRUD方法重載,我該怎麼辦?

我創建了CRUD Methods

並發現自己需要另一個(UPDATE)方法,它應該只更新兩個字段。


我應該用一個簡單的例子以良好的方式做什麼?

  1. 用我的存在的方法,填補了整個對象,並更新所有包括我打算兩個字段的字段?(無用功)與另一名
  2. - 創建靜態方法(但我要保持我的方法名的Cuz它的表現力)!!並且需要兩個參數?
+0

只需使用Overloading,創建與兩個字段更新爲同一方法的參數 – Coder1409

+0

@Coder1409實例方法或使其成爲靜態方法??因爲如果我決定用參數創建一個重載,那些參數已經是對象的一部分了! –

+0

你應該使用現有的方法。它可能覺得它工作太多,但實際上更少。你的類封裝了一個概念,即使你改變了一個屬性,該對象的狀態也在改變。使用所有屬性執行更新將強制您在更新之前瞭解所有這些屬性,這是一個很好的限制。 – boosts

回答

3

我會去通過創建兩個單獨的接口併爲每個接口創建重載函數。我會根據使用情況對屬性進行分組,例如我希望將狀態更新一段時間,使其與其他常見屬性分開。

public interface ICommonProperties 
{ 
    public string P1{get; set;} 
    public string P2{get; set;} 
    public string P3{ get; set; } 
} 
public interface ITrackable 
{ 
    public string Status{get; set;} 
} 
public class FinalClass : ICommonProperties, ITrackable 
{ 
    public string P1{get; set;} 
    public string P2{get; set;} 
    public string P3{get; set;} 
    public string Status{get; set;} 
} 

public class FinalClassOperations 
{ 
    public void Update(FinalClass finalClassInstance) { }; //Updates everything 
    public void Update(ICommonProperties finalClassInstance) { }; //Updates only ICommonProperties 
    public void Update(ITrackable finalClassInstance) { }; //updates only Status. 
} 

此外,如果你願意,你可以創建只更新狀態一個獨立的類,並且將仍適合於:

public class Tracker : ITrackable{ 
    public string Status{get; set;} 
} 

但是,是的,如果這兩個屬性不能分離出來邏輯上,我不會那樣做,並把它們放在一起。

1

這取決於你的重點是對項目內容: 使用已存在的更新方法要更新所有的一切的時候,incressing交通,IO和處理時間(驗證等等...) 如果你在一個項目中屬性被加時間戳,即使值沒有真正改變,它們也會被更新...

如果你不介意所有這些,那麼一直使用你的update()方法。

我的個人POV是:創建一個新的方法(具有明確的名稱)。這將從現在開始的相同的過程時間,並在2年的思考時間,當你不得不改變這個類;)

1

我不知道這是你應該做的必要,但這裏是你可以做的事情:創建一個SetAll或SetMany或任何你在類中傳遞的其他方法(源代碼)。檢查每個屬性,如果它非空,則將目標對象的屬性值設置爲源對象的屬性值。請注意,這種策略將取決於可空類型,並假定您可以忽略傳遞給新setter方法的空值。下面是一個例子:

using System; 

namespace BlogPartialUpdateTrick 
{ 
    public class SomeClass 
    { 
     public string FirstName { get; set; } 
     public string LastName { get; set; } 
     public int? HeightInches { get; set; } 
     public DateTime? Dob { get; set; } 

     public void SetAll(SomeClass source) 
     { 
      this.FirstName = source.FirstName ?? this.FirstName; 
      this.LastName = source.LastName ?? this.LastName; 
      this.HeightInches = source.HeightInches ?? this.HeightInches; 
      this.Dob = source.Dob ?? this.Dob; 
     } 

     public override string ToString() 
     { 
      return String.Format("fn: {0}, ln: {1}, height: {2}, DOB: {3}", FirstName ?? String.Empty, LastName ?? String.Empty, 
       HeightInches.HasValue ? HeightInches.Value.ToString() : "null", Dob.HasValue ? Dob.Value.ToShortDateString() : "null"); 
     } 
    } 
} 

在這第一個代碼示例中,我們有我的漂亮的類SomeClass。它有4個屬性,全都可以爲空。這個類的值得注意的部分是SetAllMethod,我可以傳入SomeClass類型的源對象。它將此實例的屬性值設置爲在source參數中傳遞的值,但前提是它們非空。這裏是第2個碼的Blurb在那裏我使用這個東西:

using System; 
using System.Windows.Forms; 

namespace BlogPartialUpdateTrick 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      var destination = new SomeClass() { FirstName = "Freddy", LastName = "Fingers", Dob = DateTime.Parse("01/01/1970"), HeightInches = 72 }; 
      var source = new SomeClass() { FirstName = null, LastName="Flippers", Dob = null, HeightInches = 80 }; 
      destination.SetAll(source); 
      MessageBox.Show(destination.ToString()); 
     } 
    } 
} 

創建一個目標對象,源對象,調用新的方法,瞧!輸出是這樣的:

「FN:弗雷迪,LN:腳蹼,高度:80,出生日期:1/1/1970」

1

你或許應該使用實體框架,讓背景爲你做它。使用EF,你就能夠更新實體是這樣的:

 try 
     { 
      var original = ObjectContext.Set<Request>().SingleOrDefault(x => x.Id.Equals(_request.Id)); 
      if (original != null) 
      { 
       ObjectContext.Entry(original).CurrentValues.SetValues(_request); 
      } 

      return ObjectContext.SaveChanges(); 

     } 
     catch (Exception ee) 
     { 
      return -1; 
     } 
2

我會建議遵循你的第二個選項,但沒有必要更改名稱作爲方法參數的數量上都將進行不同了 讓我們來看看幾個例子吧

我會嘗試創建一個類似的情況,我希望這是你的情況。你可以澄清,如果我錯了問題。

等級及方法

/// <summary> 
/// CLass to store properties related to database 
/// </summary> 
class ObjectoA 
{ 
    public string A{get; set;} 
    public string B{get; set;} 
    public string C{ get; set; } 
} 

/// <summary> 
/// class to call method to update. 
/// 
/// </summary> 
class ObjectB 
{ 
    /// <summary> 
    /// update method. 
    /// I would go with this solution. 
    /// optionlay you can call the method which receive parameter of object 
    /// </summary> 
    /// <param name="A"> Object with properties mapped to database</param> 
    /// <param name="updatetwoproperties">Optional paramneter to decide which update to run. 
    /// the default value should be for update that run most. For your need if you want to create an update methods for other 
    /// two sets of parameter a suggest you create an Enum and pass this enum as optional parameter instead of bool parameter or you 
    /// can pass as string and map each string value to specific update inside. IF YOU NEED EXAMPLE 
    /// REPLAY ON COMMENTS</param> 
    /// <returns></returns> 
    public bool update(ObjectoA A, bool updatetwoproperties=false) 
    { 
     //method implementation 
     if (updatetwoproperties) 
     { 
      //implement a update to all field 
     } 
     else 
     { 
      //implement update just to two field 
     } 
     return true; 
    } 

    /// <summary> 
    /// update method based on parameter to update 
    /// </summary> 
    /// <param name="a">this properties is mapped on database</param> 
    /// <param name="b">this propertie is mapped on database</param> 
    /// <returns></returns> 
    public bool update(string a, string b) 
    { 
     //method implementation e validate the return value 
     return true; 
    }  
} 

/// <summary> 
/// I don't suggest to use this solution because 
/// it will add a method on string type while this method isn't related to string 
/// I just added here as a workaround for you. 
/// </summary> 

公共靜態類ObjectC { 公共靜態布爾更新(這個字符串,字符串二) {// 執行更新和驗證返回值 回報真正; } }

調用方法和解釋

static void Main(string[] args) 
    { 
        ObjectB B = new ObjectB(); //Class with methods 
     ObjectoA A = new ObjectoA(); //object with properties 

     #region Using Optional parameter to decide which update to run 
     //Calling a method to update all columns 
     B.update(A); 
     //Calling a method to update two columns 
     B.update(A, true); 
     #endregion 

     #region Using polymorphism to update 
     //Calling a method to update all columns 
     B.update(A); 
     //Update only using paramenter 
     B.update(A.B, A.C); 
     #endregion 

     //NOT RECOMMEND BECAUSE THIS UPDATE ISN'T RELATED TO STRING TYPE 
     #region Using extension method to update 
     //Calling a method to update all columns 
     B.update(A); 
     //using the extension method on variable type 
     A.B.update(A.C); 
     #endregion 

     //WE COULD USE EXTENSION METHOD ON YOUR OBJECT BUT IT WILL FAIL BECAUSE WE ALREADY AS UPDATE METHOD ON CLASS 
     //IF YOU WANT TO SEE HOW JUST REPLAY 
    } 

我建議你添加可選的參數對你的方法來決定哪些更新爲使用