2009-06-18 20 views
5

Hoặc có thể có cách tốt hơn.Tôi có thể vượt qua T.Property không? Ngoài ra, các ý tưởng để cải thiện phương pháp này?

Tôi đang xây dựng trình tạo truy vấn động cho NHibernate, chúng tôi không muốn đặt HQL trực tiếp vào ứng dụng, chúng tôi muốn nó như ORN bất khả tri nhất có thể. Dường như hiện nay:

public override IEnumerable<T> SelectQuery(Dictionary<string, string> dictionary) 
    { 
     string t = Convert.ToString(typeof (T).Name); 
     string criteria = string.Empty; 
     foreach (KeyValuePair<string, string> item in dictionary) 
     { 
      if (criteria != string.Empty) 
        criteria += " and "; 


      criteria += item.Key + " = '" + item.Value + "'"; 
     } 

     string query = " from " + t; 

     if (criteria != string.Empty) 
      query += " where " + criteria; 

     return FindByHql(query); 
    } 

ok, tuyệt vời, tuy nhiên .... có hai điều trong đây mà đặt ra một vấn đề:

  1. Truy vấn này chỉ xử lý "và" ban đầu của tôi suy nghĩ là để vượt qua là xây dựng một phương thức để tự động xây dựng từ điển có tên thuộc tính, giá trị và toán tử "và" hoặc "hoặc" và xây dựng từ điển cùng với một loạt các toán tử. Điều đó nghe có đúng không?

  2. Ok, vì vậy, điều này làm việc TUYỆT VỜI, tuy nhiên, khi có một số nguyên nó không thành công do dấu nháy đơn. Những gì tôi nghĩ rằng sẽ là cách tốt nhất là có từ điển chấp nhận <T.Property, string> và sau đó phản ánh vào T.Property để tìm datatype và hành xử cho phù hợp. Tôi có quá phức tạp không?

Cảm ơn bạn.

Trả lời

3

Điều gì đó tương tự.

Nơi bạn có enum cho hoạt động. Thay vì truyền một chuỗi cho từ điển, bạn truyền một kiểu QueryObject có kiểu giá trị và thao tác cho giá trị. Bạn có thể xem bên dưới.

public enum Operation 
{ 
    And, 
    Or 
} 

public class QueryObject 
{ 
    public string Value { get; set; } 
    public Type Type { get; set; } 
    public Operation Operation { get; set; } 
} 

public override IEnumerable<T> SelectQuery(Dictionary<string, QueryObject> dictionary) 
{ 
    string t = Convert.ToString(typeof(T).Name); 
    string criteria = string.Empty; 
    foreach (KeyValuePair<string, QueryObject> item in dictionary) 
    { 
     if (!string.IsNullOrEmpty(criteria)) 
     { 
      switch (item.Value.Operation) 
      { 
       case Operation.And: 
        criteria += " and "; 
        break; 
       case Operation.Or: 
        criteria += " or "; 
        break; 
       default: 
        break; 
      } 
     } 

     if (item.Value.Type == typeof(int)) 
     { 
      criteria += item.Key + " = " + item.Value + " ";  
     } 
     else 
     { 
      criteria += item.Key + " = '" + item.Value + "'"; 
     } 
    } 

    string query = " from " + t; 

    if (criteria != string.Empty) 
     query += " where " + criteria; 

    return FindByHql(query); 
} 
+0

tôi đã sử dụng này, ngoại trừ tôi đã đi với các từ điển tất cả cùng nhau và chỉ cần thêm "tài sản" như chuỗi các lớp QueryObject. Cảm ơn! –

1

tôi sẽ đề nghị có thể tạo ra một lớp học có tất cả các thuộc tính bạn cần:

Name, 
Value, 
Type, 
JoinType (possibly an enum with Or/And) 

sau đó, có phương pháp của bạn có một bộ sưu tập các loại như trái ngược với một từ điển. Bằng cách này, bạn có thể dễ dàng kiểm tra xem bạn có cần phải làm và/hoặc, cũng như kiểm tra xem bạn có cần báo giá hay không ...

1

Suy nghĩ của tôi là tạo ra thứ gì đó như thế này không quá hợp lý. Bạn đang viết mã tạo HQL. Mà lần lượt được truyền cho nhibernate mà tạo ra SQL.

Tôi khuyên bạn nên xem NHibernate criteria truy vấn. Thứ nhất là một cách dễ dàng hơn để tự động xây dựng một truy vấn NHibernate. Nhưng cũng để cung cấp cho bạn một số loại ý tưởng về việc việc tạo trình tạo truy vấn động của riêng bạn phức tạp như thế nào.

Điều đó nói. Nếu tôi đã làm nó tôi có lẽ sẽ sử dụng NHibernate Tiêu chí như là một cơ sở cho bất kỳ loại xây dựng truy vấn năng động. Không có lý do tại sao nó không thể tạo ra một truy vấn được sử dụng bởi ORM khác.

Giải pháp tổng quát hơn cho vấn đề là trừu tượng truy cập dữ liệu của bạn để nếu bạn muốn chuyển đổi ORM thì bạn chỉ cần thay đổi mã đằng sau sự trừu tượng của bạn. Đây là công việc nhiều hơn tất nhiên nhưng tôi không tin rằng việc giữ mã truy cập dữ liệu của bạn ORM độc lập là một cái gì đó đặc biệt quan trọng.

+0

truy vấn tiêu chí là một cách tốt để đi, nhưng tôi ở lại với thiết lập hiện tại của tôi theo tinh thần "nhận được thực hiện" –

0

Một thay thế cho những gì bạn đang làm là chuyển Biểu thức> thay vì từ điển và sau đó phân tích biểu thức LINQ cho những gì bạn muốn. Một gợi ý nhỏ mà tôi sẽ thực hiện là sử dụng truy vấn Tiêu chí thay vì HQL. Tất nhiên phân tích cú pháp biểu thức LINQ có lẽ phức tạp hơn nhiều so với những gì bạn có ở đây.

Bạn có thể xử lý từ điển và tạo HQL tuyệt vời, nhưng nó làm tôi đau đầu khi nghĩ về cách đó. Truy vấn tiêu chí dường như được thiết kế cho loại điều này.

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