2012-03-31 32 views
7

Tôi có một mã như thế này:Làm thế nào để xác định cấu trúc LINQ của riêng tôi trong C#?

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(); 
     } 
    } 
    //... 
}  

Chúng ta có thể nhận thấy một số sự lặp lại nhàm chán trong các mã.

Vì vậy, nó sẽ được tốt đẹp để viết một phương thức Update chung trong một cách mà chúng tôi có thể đủ khả năng mình để viết một cái gì đó như thế này:

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

Nói cho tôi biết, làm ơn, là nó có thể để viết một phương pháp như vậy?

Tôi có thể tìm hiểu sách từ đâu?

(Tôi đã tìm thấy chỉ là một ví dụ gần: http://msdn.microsoft.com/en-us/library/cc981895.aspx, nhưng nó không phải là đủ rõ ràng làm thế nào để lấy được phương thức Update của tôi từ đó)

Cảm ơn bạn.

UPD.

Ok, Jon Skeet nói có điều gì đó sai trong câu hỏi, và tôi đồng ý, rằng cuộc gọi của tôi nên nhìn khác nhau, tôi nghĩ rằng những cuộc gọi có thể xảy ra:

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

Có phương pháp giống như LINQ cập nhật dữ liệu là một chút không tự nhiên – zerkms

+1

Một cuốn sách tôi muốn đề xuất là [Pro Linq] (http://www.amazon.com/Pro-LINQ-Language-Integrated-Experts/ dp/1590597893). –

Trả lời

10

Hãy bắt đầu bằng cách viết một hàm helper bình thường. Điều này không liên quan gì đến 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(); 
    } 
} 

Vì vậy, bạn thấy, bạn có thể sử dụng đại diện cập nhật để trích xuất đoạn mã nhỏ duy nhất khác nhau cho mỗi cuộc gọi. Phần còn lại là như nhau, và bây giờ chúng ta có nó tập trung và reusabe.

Bạn cũng có thể thực hiện phương pháp chung:

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(); 
    } 
} 

Nếu bạn muốn có bộ lọc tự động, bạn cần phải sử dụng các biểu thức và phản xạ API để xây dựng các biểu thức lọc. Mã cho điều đó dài hơn một chút.

+4

Lưu ý rằng chúng tôi thậm chí không sử dụng một phương pháp mở rộng. Nó không cần thiết ở đây. Đi đơn giản khi đơn giản là đủ. – usr

+2

Thay vì viết nhận xét cho câu trả lời của riêng bạn, bạn có thể thêm thông tin bổ sung trực tiếp vào câu trả lời bằng cách chỉnh sửa :) –

+0

Có, nhưng nếu chúng ta cần phương thức cập nhật cho một trường đơn lẻ khác với Gói, chúng tôi sẽ nhận mã lặp lại trong lớp trừu tượng cao hơn một chút, khi chúng ta viết gần như cùng một hàm trợ giúp với một chữ ký nói static void UpdateMessage (int messageId, Action update). – gentlenub

Các vấn đề liên quan