2011-12-06 36 views
6

Tôi đang gặp một chút rắc rối khi quyết định cách tốt nhất để cấu trúc lại phương thức chứa truy vấn LINQ rất giống nhưng không giống nhau.Phương pháp tái cấu trúc chứa truy vấn LINQ

Hãy xem xét một phương pháp đó là một cái gì đó dọc theo những dòng:

public SomeObject GetTheObject(IMyObject genericObject) { 
    Type t = genericObject.GetType(); 
    SomeObject so = null; 

    switch(t.Name) { 
     case "Type1": 
      var object1 = (from o in object1s where o.object1id == genericObject.id).FirstOrDefault(); 
      so = (SomeObject)object1; 
     break; 
     case "Type2": 
      var object2 = (from o in object2s where o.object2id == genericObject.id).FirstOrDefault(); 
      so = (SomeObject)object2; 
     break; 
     default: 
     break; 
    } 

    return so; 
} 

Đây chỉ là một minh hoạ, nhưng hãy tưởng tượng tôi cần phải thực hiện một truy vấn khác nhau (khác nhau ở chỗ nó sử dụng một ObjectSet khác nhau, sử dụng hơi các trường khác nhau (object1id vs object2id) và trả về một kiểu khác nhau Ngoài ra, các truy vấn là giống nhau

Có cách nào hợp lý để cấu trúc lại kiểu phương pháp này không? Có lẽ tôi phải sử dụng phương pháp chính xác và tôi không thể tránh viết lại truy vấn, nó chỉ cần ems như tôi NÊN có thể bằng cách nào đó!

Bất kỳ con trỏ đánh giá rất

+0

Tôi đã thử nó với Reflection, nhưng anh ta lại quá khứ tuyên bố LINQ ("từ o trong object1s nơi o.object1id"). Bạn nên xem xét tạo động một câu lệnh LINQ. – Graham

+0

Hi Graham, điều này chắc chắn sẽ là một lựa chọn ngoại trừ một thực tế là tôi đang cố gắng giữ DAL đóng gói trong một kho lưu trữ mà lá tôi bị hạn chế trong các phương pháp tôi có thể sử dụng để tự động xây dựng một truy vấn. Tôi đã cố gắng xây dựng một nhà máy để trả lại bản sao Repository cụ thể mà tôi muốn. Nhưng điều này đã để lại cho tôi một tình huống tương tự như tôi đã mô tả cho Paolo, cụ thể là bởi vì Repository của tôi yêu cầu một kiểu EntityObject cụ thể, nên tôi không thể tạo một kiểu dựa trên một giao diện. – dougajmcdonald

Trả lời

4

Có lẽ bạn đã chỉ quá đơn giản hóa kịch bản của bạn, nhưng phần mùi của chức năng của bạn là diễn viên để SomeObject. Bạn không thể chỉ làm việc với các giao diện và (nếu cần thiết) đúc kết quả tại trang web cuộc gọi? Bạn có thể có Type1 và Type2 của bạn thực hiện một giao diện chung nơi id1 và id2 được hiển thị dưới dạng id, ví dụ (hoặc trang trí chúng nếu bạn không kiểm soát Type1 và Type2)

I.e.

public static IMyObject GetTheObject(List<IMyObject> theList, int id) 
{ 
    var ret = (from o in theList 
     where o.id==id 
     select o).FirstOrDefault(); 

    return ret; 
} 

Ví dụ, nếu bạn có:

public interface IMyObject {int id {get;}} 

    public class Foo : IMyObject {public int id {get; set;}} 
    public class Bar : IMyObject {public int id {get; set;}} 

bạn có thể làm:

var l1 = new List<IMyObject>(){new Foo(){id=1}, new Foo(){id=2}}; 
var l2 = new List<IMyObject>(){new Bar(){id=1}, new Bar(){id=2}}; 

var obj1 = Test.GetTheObject(l1, 1); 
var obj2 = Test.GetTheObject(l2, 2); 

Và đúc các đối tượng sau khi bạn gọi hàm, nếu bạn phải.

EDIT: nếu bạn đang mắc kẹt với các đối tượng và các cặn lắng bê tông, refactoring tốt nhất mà tôi có thể đưa ra là:

public static SomeObject GetTheObject(IMyObject genericObject) { 
    Type t = genericObject.GetType(); 

    Func<SomeObject, bool> WhereClause = null; 
    IEnumerable<SomeObject> objs = null; // IEnumerable<T> is covariant, 
         // so we can assign it both an IEnumerable<object1> 
         // and an IEnumerable<object2> (provided object1 and 2 are 
         // subclasses of SomeObject) 

    switch(t.Name) { 
     case "Type1": 
      WhereClause = o => ((Object1)o).object1id == genericObject.id;  
      objs = object1s; 
     break; 
     case "Type2": 
      WhereClause = o => ((Object2)o).object2id == genericObject.id;  
      objs = object2s; 
     break; 
    } 

    var ob = objs 
    .Where(WhereClause) 
    .FirstOrDefault(); 

    return (SomeObject)ob; 
} 
+0

Vâng tôi nghĩ rằng tôi đã đơn giản hóa mọi thứ một chút, vấn đề tôi gặp phải khi làm việc với giao diện là truy vấn của tôi thực sự là một truy vấn trên một kho lưu trữ chung đòi hỏi một loại cụ thể. Điều này có nghĩa là tôi không thể thực hiện Respository vào lúc này đang khiến tôi đau buồn. Tôi có thể giả sử viết một kho lưu trữ khác ở đó T: IMyObject, chứ không phải là T: EntityObject hiện tại, nhưng cảm giác như quá mức cần thiết, tuy nhiên nó có thể cần thiết. – dougajmcdonald

+0

@dougajmcdonald: việc tái cấu trúc mà tôi có thể nghĩ ra không giống như cải thiện của bạn, nhưng ít nhất nó làm giảm sự trùng lặp trong mã LINQ ... :) –

+0

cảm ơn vì điều đó, tôi sẽ có một trò chơi khi tôi nhận được một cơ hội vào thứ năm, tôi đã hy vọng để có được từ logic chuyển đổi như trong tình hình thực tế cuộc sống của tôi tôi có thể có 10-12 lựa chọn và tôi không muốn bung lên màn hình với các báo cáo trường hợp!sau đó một lần nữa nó có thể là lựa chọn duy nhất! – dougajmcdonald

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