2012-03-31 45 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

相关问题