2011-11-15 25 views
9

Ra khỏi tò mò tôi muốn biết làm thế nào để thực hiện tốt nhất một lớp học mà có thể được sử dụng để tránh những cảnh báo CA1006Làm thế nào để thực hiện chung IEnumerable hoặc IDictionary để tránh CA1006?

CA1006: Microsoft.Design: Xem xét một thiết kế nơi 'IReader.Query (String, String) 'không tổ chung loại' IList (Of IDictionary (Of String, Object)) '.

Đây là phương pháp mà trả về kiểu generic

public virtual IList<IDictionary<string, object>> Query(
    string fullFileName, 
    string sheetName) 
{ 
    using (var connection = new OdbcConnection(
     this.GetOdbcConnectionString(fullFileName))) 
    { 
     connection.Open(); 
     return connection 
      .Query(string.Format(
       CultureInfo.InvariantCulture, 
       SystemResources.ExcelReader_Query_select_top_128___from__0_, 
       sheetName)) 
      .Cast<IDictionary<string, object>>() 
      .ToList(); 
    } 
} 

Something như

SourceData<T, U> Query(string fullFileName, string sheetName) 
SourceData Query(string fullFileName, string sheetName) 

EDIT:

Tiếp theo gợi ý của Marc tôi đóng gói các generic lồng nhau trong lớp này

public class QueryRow : List<KeyValuePair<string, object>> 
{ 
    protected internal QueryRow(IEnumerable<KeyValuePair<string, object>> dictionary) 
    { 
     this.AddRange(dictionary.Select(kvp => kvp)); 
    } 
} 
+0

ý định của danh sách từ điển ở đây là gì? là các hàng, với các giá trị được khóa (tức là các ô được truy cập theo tên cột)? –

+0

mỗi từ điển là một hàng mà mỗi khóa là tiêu đề cột và giá trị là giá trị ô – mrt181

+0

Thay cho '.Cast', bạn có thể không sử dụng' .ToDictionary' không? – IAbstract

Trả lời

12

Trước tiên, lưu ý rằng đó là thiết kế hướng dẫn, không phải lỗi trình biên dịch. Một cách tiếp cận hợp lệ ở đây sẽ là: bỏ qua nó.

Thứ khác có thể là - gói gọn nó; tức là trả lại một List<QueryRow>, nơi QueryRow là một wrapper cạn trên một IDictionary<string,object> với một indexer, tức là

public class QueryRow { 
    private readonly IDictionary<string,object> values; 
    internal QueryRow(IDictionary<string,object> values) { 
     this.values = values; 
    } 
    public object this[string key] { 
     get { return values[key]; } 
     set { values[key] = value; } 
    } 
} 

sau đó, vì điều này đang được truy cập thông qua hoạt bát, điền qua:

var data = connection.Query(....) 
     .Select(x => new QueryRow((IDictionary<string,object>)x).ToList() 

Một lựa chọn khác (mà Tôi không thích lắm), có thể là: return DataTable.

sẽ tắt để rửa tay sau khi nhập DataTable ... gah! hai lần bây giờ

+0

tôi gần như puked khi tôi đọc trở lại DataTable;) – mrt181

+0

ok, tôi đã thử nó theo cách này. Không hoạt động. Tôi nhận được thông báo này 'System.ArgumentNullException: Parametername: con bei System.Reflection.Emit.DynamicILGenerator.Emit (opcode opcode, ConstructorInfo con) bei Dapper.SqlMapper.GetClassDeserializer (IDataReader reader, Int32 startBound, chiều dài Int32, Boolean returnNullIfFirstMissing) trong SqlMapper.cs: dòng 1227.' khi tôi thêm một hàm tạo parameterless, truy vấn trả về một IEnumerable nhưng thuộc tính value là null. – mrt181

+0

@mrt woah, hoàn toàn không nhận thấy rằng đây là "dapper". Không có gì trong câu hỏi ban đầu được đề xuất "dapper" với tôi! Nhưng: trong trường hợp này, bạn sẽ có thể sử dụng phương thức Query() không chung chung, sau đó cast từng lượt, nghĩa là 'connection.Query (....). Chọn (x => new QueryRow ((IDictionary ) x) .ToList() '- sử dụng bất kỳ? –

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