2012-03-31 74 views
7

我有這樣的代碼:如何在C#中定義我自己的LINQ結構?

class PacketDAO{ 
    //... 
    public void UpdatePacketStatus(Guid packetID, Status status) 
    { 
     using (var ctx = new DataContext()) 
     { 
      var packet = ctx.Packet.SingleOrDefault(p => p.PacketID == packetID); 
      packet.Status = status; 
      ctx.SubmitChanges(); 
     } 
    } 

    public void UpdatePacketTime(Guid packetID, DateTime? time) 
    { 
     using (var ctx = new DataContext()) 
     { 
      var packet = ctx.Packet.SingleOrDefault(p => p.PacketID == packetID); 
      packet.Time = time; 
      ctx.SubmitChanges(); 
     } 
    } 
    //... 
}  

我們可以看到在代碼中的一些無聊的重複。

所以,這將是很好寫的方式,我們能買得起自己來寫這樣的一個通用的方法更新:

packet.Update<Guid, Packet>(guid, p => p.Time = DateTime.Now); 
packet.Update<Guid, Packet>(guid, p => p.Status = Status.Ok); 

請告訴我,是有可能寫出這樣的方法?

我可以從中學習哪本書?

(我只找到一個接近例如:http://msdn.microsoft.com/en-us/library/cc981895.aspx,但它是不夠清楚如何推導從我的更新方法)

謝謝。

UPD。

好吧,喬恩斯基特告訴有什麼不對的問題,我同意,我的電話應該是不同的,我覺得這些電話是可能的:

packet.Update<Packet>(p => p.packetID == guid, p => p.Time = DateTime.Now); 
packet.Update<Packet>(p => p.packetID == guid, p => p.Status = Status.Ok); 
+0

擁有類似LINQ的方法更新數據有點不自然 – zerkms 2012-03-31 12:46:50

+1

我推薦的一本書是[Pro Linq](http://www.amazon.com/Pro-LINQ-Language-Integrated-Experts/ DP/1590597893)。 – 2012-03-31 12:47:11

回答

10

讓我們寫一個普通的輔助功能啓動。這與LINQ無關。

public static void UpdatePacket(Guid packetID, Action<Packet> update) 
{ 
    using (var ctx = new DataContext()) 
    { 
     var packet = ctx.Packet.SingleOrDefault(p => p.PacketID == packetID); 
     update(packet); 
     ctx.SubmitChanges(); 
    } 
} 

所以你看,你可以使用update-delegate來提取每個調用中唯一不同的一小段代碼。其餘的都是一樣的,現在我們把它集中起來並且可以重複使用。

您也可以使該方法一般:

public static void UpdatePacket<TEntity>(Expression<Func<TEntity, bool>> filter, Action<TEntity> update) 
{ 
    using (var ctx = new DataContext()) 
    { 
     var e = ctx.GetTable<TEntity>().Single(filter); 
     update(e); 
     ctx.SubmitChanges(); 
    } 
} 

如果你想擁有過濾器的自動化,您需要使用表達式和反射API來構建過濾器表達式。該代碼稍長一些。

+4

請注意,我們甚至沒有使用擴展方法。這裏不需要。當簡單就夠了的時候簡單點吧。 – usr 2012-03-31 12:57:35

+2

不是給自己的答案寫評論,而是通過編輯它直接將其他信息添加到答案:) – 2012-03-31 12:58:57

+0

是的,但是如果我們需要一個不同於數據包的表的單個字段的更新方法,我們將獲得代碼重複在更高層的抽象,因爲我們寫了幾乎相同的幫助函數與簽名說靜態無效UpdateMessage(int messageId,動作更新)。 – gentlenub 2012-03-31 16:44:02

相關問題