2012-06-30 34 views
9

Hiện nay, tôi đang sử dụng một cái gì đó như thế này:Làm cách nào để có thể ánh xạ kết quả của truy vấn sql lên các đối tượng?

try 
    { 
     dr = SQL.Execute(sql); 

     if(dr != null) { 
     while(dr.Read()) { 
      CustomObject c = new CustomObject(); 
      c.Key = dr[0].ToString(); 
      c.Value = dr[1].ToString(); 
      c.Meta = dr[2].ToString(); 
      customerInfo.CustomerList.Add(c); 
     } 
     } 
     else 
     { 
      customerInfo.ErrorDetails="No records found"; 
     } 

Thay vì tôi làm assigments bằng tay, là có một cách để làm bản đồ này trực tiếp (giả định rằng tên cột phù hợp với tên trường).

Một yêu cầu, tuy nhiên là tôi muốn làm điều này bằng cách tiếp cận hiện tại của tôi về sử dụng truy vấn sql và không phải bằng cách sử dụng phương pháp tiếp cận dựa trên LINQ thuần túy. Đối với một, các truy vấn SQL là đủ lớn, liên quan đến JOIN phức tạp và đã được kiểm tra kỹ lưỡng vì vậy tôi không muốn giới thiệu thêm lỗi tại thời điểm này. Bất kỳ đề xuất?

+2

Lưu ý rằng bạn * có thể * sử dụng LINQ với các truy vấn SQL tùy chỉnh và nó sẽ tự động ánh xạ các trường trong kết quả truy vấn đến loại đối tượng chung mà bạn cung cấp. Xem [** 'DataContext.ExecuteQuery' **] (http://msdn.microsoft.com/en-us/library/bb361109.aspx) – mellamokb

+0

@mellamokb: Bạn có thể chỉ cho tôi cách thực hiện không? Hoặc ít nhất là chỉ cho tôi một số tài nguyên hoặc có lẽ những gì tôi nên tìm kiếm? – Legend

+0

Hãy xem liên kết tôi đã thêm vào, đó là phương pháp cụ thể bạn cần. Ngoài ra còn có các ví dụ trên trang đó. – mellamokb

Trả lời

4

Một giải pháp đơn giản là tạo một hàm tạo cho số CustomObject lấy DataRow (từ ví dụ này, vì vậy nếu đó là một lớp khác, hãy sửa tôi).

Và trong nhà xây dựng mới của bạn, hãy làm như bạn làm trong ví dụ của riêng bạn.

public CustomObject(DataRow row) 
{ 
    Key = row[0].ToString(); 
    // And so on... 
} 

Một cách khác sẽ được giới thiệu Generics, và thực hiện một chức năng mới trong SQL-lớp học của bạn

Ví dụ (Took mã từ Passing arguments to C# generic new() of templated type): sử dụng

// This function should reside in your SQL-class. 
public IEnumerable<T> ExecuteObject<T>(string sql) 
{ 
    List<T> items = new List<T>(); 
    var data = ExecuteDataTable(sql); // You probably need to build a ExecuteDataTable for your SQL-class. 
    foreach(var row in data.Rows) 
    { 
     T item = (T)Activator.CreateInstance(typeof(T), row); 
     items.Add(item); 
    } 
    return items; 
} 

Ví dụ:

public IEnumerable<CustomObject> GetCustomObjects() 
{ 
    return SQL.ExecuteObject<CustomObject>("SELECT * FROM CustomObject"); 
} 

Tôi đã thử nghiệm mã này trong LinqPad, nó sẽ hoạt động.

3

Bạn có thể đạt được bằng cách tạo phương pháp chung cho yêu cầu của mình. Ngoài ra, bạn có thể làm cho phương thức mới của mình là phần mở rộng cho bảng dữ liệu.

public static List<T> ToList<T>(this DataTable table) where T : class, new() 
{ 
    try 
    { 
     List<T> list = new List<T>(); 

     foreach (var row in table.AsEnumerable()) 
     { 
      T obj = new T(); 

      foreach (var prop in obj.GetType().GetProperties()) 
      { 
       try 
       { 
        PropertyInfo propertyInfo = obj.GetType().GetProperty(prop.Name); 
        propertyInfo.SetValue(obj, Convert.ChangeType(row[prop.Name], propertyInfo.PropertyType), null); 
       } 
       catch 
       { 
        continue; 
       } 
      } 

      list.Add(obj); 
     } 

     return list; 
    } 
    catch 
    { 
     return null; 
    } 
} 

}

Cách sử dụng:

DataTable dtCustomer = GetCustomers(); 
    List<CustomObject> CustomObjectList = dtCustomer.ToList<CustomObject>(); 
2

Bạn nên nhìn vào MicroORMs. Không giống như các ORM thông thường, cung cấp SDL mà bạn phải sử dụng, MicroORM cho phép bạn sử dụng các truy vấn SQL của riêng bạn và chỉ cung cấp ánh xạ từ các tập kết quả SQL tới các đối tượng C# và từ các đối tượng C# đến các tham số SQL.

Yêu thích của tôi là PetaPoco, cũng cung cấp trình tạo truy vấn sử dụng SQL của riêng bạn nhưng thực hiện một số thao tác gọn gàng các số tham số.

0

Hàm sau chấp nhận một chuỗi SQL và một đối tượng, nó yêu cầu đối tượng có thuộc tính cho mỗi cột trong câu lệnh chọn. Đối tượng phải được khởi tạo.

đối tượng nào SqlToSingleObject (string sSql, đối tượng o) {

 MySql.Data.MySqlClient.MySqlDataReader oRead; 
     using (ConnectionHelper oDb = new ConnectionHelper()) 
     { 
      oRead = oDb.Execute(sSql); 
      if (oRead.Read()) 
      { 

       for (int i = 0; i < oRead.FieldCount; i++) 
       { 

        System.Reflection.PropertyInfo propertyInfo = o.GetType().GetProperty(oRead.GetName(i)); 
        propertyInfo.SetValue(o, Convert.ChangeType(oRead[i], propertyInfo.PropertyType), null); 
       } 
       return o; 
      } 
      else 
      { 
       return null; 

      } 

     } 

    } 
+0

Whats điểm đó? Nếu bạn định tạo ra tất cả các poperties, tại sao không chỉ tự xây dựng đối tượng. – MattE

1

Assumption: nếu bạn cần các đối tượng chỉ cho serialization hoặc đầu ra ad-hoc đơn giản.

Bạn có thể sử dụng ExpandoObjectSqlDataReader.GetSchemaTable() như thế này:

private IEnumerable<dynamic> ReaderToAnonymmous(SqlCommand comm) { 
     using (var reader = comm.ExecuteReader()) { 
      var schemaTable = reader.GetSchemaTable(); 

      List<string> colnames = new List<string>(); 
      foreach (DataRow row in schemaTable.Rows) { 
       colnames.Add(row["ColumnName"].ToString()); 
      } 

      while (reader.Read()) { 
       var data = new ExpandoObject() as IDictionary<string, Object>; 
       foreach (string colname in colnames) { 
        var val = reader[colname]; 
        data.Add(colname, Convert.IsDBNull(val) ? null : val); 
       } 

       yield return (ExpandoObject)data; 
      } 
     } 
    } 

Mặc dù có được đăng các giải pháp nhanh hơn (i posted phương pháp lười biếng như thay thế này cho ad-hoc kết quả SQL/Reader/đầu ra).

+0

điều này thật tuyệt vời, chính xác những gì tôi đang tìm kiếm. Tôi là giao diện điều khiển ứng dụng tạo ra các báo cáo trong excel từ các thủ tục được lưu trữ, và với đoạn mã này tôi không phải lập bản đồ các thủ tục trong ứng dụng. Cảm ơn bạn. – v1n1akabozo

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