2014-12-04 47 views
6

我有很多方法在大部分的后面跟着相同的算法,我理想地希望能够调用一个消除大量代码重复的泛型方法。有大量代码重复的问题

我有一大堆像下面的那些方法,我会最佳希望能够只是调用 Save<SQLiteLocation>(itemToSave);我却带来很大的麻烦,因为这些方法 SQLiteConnection.Find<T>不会接受如T抽象数据类型在泛型中。

有什么办法来解决这个问题,如果我能得到它固定的,我会保存代码多达150线

这里是我的代码:

public bool SaveLocation(ILocation location, ref int primaryKey) 
    { 
     var dbConn = new SQLiteConnection (dbPath); 

     SQLiteLocation itemToSave = new SQLiteLocation(); 
     itemToSave.LocationName = location.LocationName; 
     itemToSave.Latitude = location.Latitude; 
     itemToSave.Longitude = location.Longitude; 
     itemToSave.PrimaryKey = location.PrimaryKey; 

    ---------------------------------------------------------------------------------------- 

     SQLiteLocation storedLocation = dbConn.Find<SQLiteLocation> 
             (x => x.PrimaryKey == location.PrimaryKey); 

     if (storedLocation != null) 
     { 
      dbConn.Update(itemToSave); 
      return true; 
     } 

     else if (storedLocation == null) 
     { 
      dbConn.Insert(itemToSave); 
      primaryKey = itemToSave.PrimaryKey; 
      return true; 
     } 
     return false; 
    } 

这里的另一种方法怎么看在我的虚线下面两种方法的代码基本上

public bool SaveInvitation(IInvitation invitation, ref int primaryKey) 
    { 
     var dbConn = new SQLiteConnection(dbPath); 

     SQLiteInvitation itemToSave = new SQLiteInvitation(); 
     itemToSave.GroupName = invitation.GroupName; 
     itemToSave.InviterName = invitation.InviterName; 
     itemToSave.ParseID = invitation.ParseID; 
     itemToSave.GroupParseID = invitation.GroupParseID; 
     itemToSave.PrimaryKey = invitation.PrimaryKey; 

--------------------------------------------------------------------------------------- 

     SQLiteInvitation storedInvitation = dbConn.Find<SQLiteInvitation> 
              (x => x.PrimaryKey == invitation.PrimaryKey); 

     if (storedInvitation != null) 
     { 
      dbConn.Update(itemToSave); 
      return true; 
     } 
     else if (storedInvitation == null) 
     { 
      dbConn.Insert(itemToSave); 
      primaryKey = itemToSave.PrimaryKey; 
      return true; 
     } 
     return false; 
    } 
+0

您可以使用AutoMapper或类似的东西来移动性能。另外,如果您将'itemToSave'移出方法并将其作为参数传递,那么我相信您可以使其他代码通用。 – 2014-12-04 20:01:28

+0

您是否考虑过寻找表达式树来构建“查找”声明? – 2014-12-04 20:02:23

+0

'storedX'或者是null,所以不需要使用else if。由于这个原因,你永远不会返回false,所以你可以删除返回值。左边是'if(storedX!= null){dbConn.Update(itemToSave); } else {dbConn.Insert(itemToSave); primaryKey = itemToSave.PrimaryKey; }'。删除了3行 – Default 2014-12-04 20:17:21

回答

0

出于某种原因,引发了不支持的异常 当我用:

T storedItem = dbConn.Find<T>(x => x.PrimaryKey == item.PrimaryKey); 

下面的代码固定我的困境虽然,谢谢大家的帮助,我喜欢这个网站! 此外,我增加了一个限制对T看到为T必须是一个非抽象类和接口仅仅是我想

private void SaveItem<T>(T item, ref int primaryKey) 
     where T : ISQLiteClass, new() 
    { 
     var dbConn = new SQLiteConnection(dbPath); 

     T storedItem = dbConn.Find<T>(primaryKey); 

     if (storedItem != null) 
     { 
      dbConn.Update(item); 
     } 
     else if (storedItem == null) 
     { 
      dbConn.Insert(item); 
      primaryKey = item.PrimaryKey; 
     } 
    } 
1

你不应该能够做这样的事同样的事情: 注:ICOMM onInterface是你希望用作T的任何允许类之间通用的任何东西。最好查看你的代码,暴露PrimaryKey属性的接口或类。

public bool SaveItem<T>(T item, ref int primaryKey) where T : ICommonInterface, new() 
{ 
    var dbConn = new SQLiteConnection(dbPath); 


    T storedItem = dbConn.Find<T>(x => x.PrimaryKey == item.PrimaryKey); 

    if (storedItem != null) 
    { 
     dbConn.Update(item); 
     return true; 
    } 
    else if (storedItem == null) 
    { 
     dbConn.Insert(item); 
     primaryKey = item.PrimaryKey; 
     return true; 
    } 
    return false; 
} 

编辑:添加新的()约束的方法。

+0

你是正确的这固定我的代码,你保存了我的许多行代码 – Guano 2014-12-04 21:28:02

+0

其实它看起来我太过皮疹,我得到这个错误:\t \t \t'T '必须是具有公共无参数构造函数的非抽象类型,才能将其用作通用类型或方法'SQLite'中的参数'SQLite.SQLiteConnection.Find (System.Linq.Expressions.Expression > )'(CS0310)(ShoppingAssistant) – Guano 2014-12-04 22:13:01

+0

查看修改后的答案。为该方法添加一个新的()约束。 ex:where T:ICommonInterface,new() – gmiley 2014-12-05 12:20:09