我有这样的代码:
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();
}
}
//...
}
我们可以注意到代码中有些无聊的重复。
因此,以一种我们可以负担得起的方式编写一个通用的方法Update会很好:
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,但是不清楚如何从中推导出我的Update方法。
谢谢。
UPD。
好的,Jon Skeet告诉我这个问题有问题,我同意,我的电话应该看起来不一样,我认为这些电话是可能的:
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 :(得分: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();
}
}
如果要使过滤器自动化,则需要使用Expression和reflection API来构造过滤器表达式。这段代码要长一点。