2010-11-18 33 views
7

Tôi cần lấy hai trường từ bảng cơ sở dữ liệu (được truy xuất bằng LINQ-to-sql), một trường là datetime (và là trường cố định) và trường kia luôn là một số thập phân, nhưng trường có thể khác nhau.Sử dụng biểu thức Lambda để chọn các trường khác nhau từ tên trường

Bảng giữ dữ liệu tiền tệ được xử lý hai lần một ngày và bằng các đơn vị tiền tệ khác nhau để có thể có các trường như AM_USD, PM_USD, AM_EUR v.v ... và tôi cần lấy dữ liệu như danh sách ngày chống lại PM_USD hoặc ngày chống lại AM_EUR.

Tôi muốn để có thể gọi là dữ liệu sử dụng một biểu thức lambda ví dụ (đây là một tước ra ví dụ):

data = TableData.Select(x=>new {x.DateTimeAdded, x.[**field name as string**]}); 

Tôi đã cố gắng để viết một chức năng để làm điều này, và tôi thất bại.

Gần nhất tôi đã được quản lý là:

private Func<TableData, KeyValuePair<DateTime, decimal>> CreateSelect(string FieldName) 
{ 
    var parameterExp = Expression.Parameter(typeof(TableData), "sel"); 
    var dateParameter = Expression.Parameter(typeof(DateTime), "DateTimeAdded"); 
    var fieldParameter = Expression.Parameter(typeof(decimal), FieldName); 
    ConstructorInfo constructorInfo = typeof(KeyValuePair<DateTime, decimal>).GetConstructor(new[] { typeof(DateTime), typeof(decimal) }); 
    NewExpression constructExpression = Expression.New(constructorInfo, new ParameterExpression[] { dateParameter, fieldParameter}); 

    var lambda = Expression.Lambda<Func<TableData, KeyValuePair<DateTime, decimal>>>(constructExpression, parameterExp); 

    return lambda.Compile(); 
} 

nào không thành công với "System.InvalidOperationException: Lambda Parameter không trong phạm vi".

Tôi chắc chắn rằng tôi thiếu điều gì đó hiển nhiên hoặc đi sai đường.

Bất kỳ ý tưởng nào?

Cảm ơn T

+0

Có công bằng để giả định rằng bạn không thể thay đổi lược đồ khủng khiếp đó cho dữ liệu không? – Lazarus

Trả lời

4

x.Foo là một viên của x (bất động sản hoặc trường), không phải là một tham số:

private Func<TableData, KeyValuePair<DateTime, decimal>> CreateSelect(string FieldName) 
{ 
    var parameterExp = Expression.Parameter(typeof(TableData), "sel"); 
    var dateProp = Expression.PropertyOrField(parameterExp, "DateTimeAdded"); 
    var fieldProp = Expression.PropertyOrField(parameterExp, FieldName); 
    ConstructorInfo constructorInfo = typeof(KeyValuePair<DateTime, decimal>).GetConstructor(new[] { typeof(DateTime), typeof(decimal) }); 
    NewExpression constructExpression = Expression.New(constructorInfo, new [] { dateProp, fieldProp}); 

    var lambda = Expression.Lambda<Func<TableData, KeyValuePair<DateTime, decimal>>>(constructExpression, parameterExp); 

    return lambda.Compile(); 
} 
+0

Xin chào Marc, đây là một câu trả lời tuyệt vời và đang trả lại cảm giác đúng, nhưng bây giờ tôi sẽ nghe có vẻ ngu ngốc ... Làm cách nào để gọi phương thức này? var data = TableData.Select (CreateSelect ("tên trường")); quay trở lại với một System.ArgumentNullExpception và yêu cầu tôi "Thử chỉ định các đối số kiểu giải thích" Cảm ơn T –

+0

@Toby - Lỗi ở đâu? –

+0

@Marc - Nó sẽ không cho phép tôi biên dịch mã. Dòng này hoạt động ok: var tst = CreateSelect ("AMUSD"); Nhưng nếu tôi thử một cái gì đó như data.Select (CreateSelect ("AMUSD")); nó sẽ không cho phép tôi biên dịch. –

3

Từ câu hỏi của bạn:

data = TableData.Select(x=>new {x.DateTimeAdded, x.[**field name as string**]}); 

Xác định lĩnh vực này tên trong truy vấn LINQ dưới dạng chuỗi có thể được thực hiện bằng cách sử dụng the LINQ Dynamic Query Library.

You can use the DynamicQuery library against any LINQ data provider (including LINQ to SQL, LINQ to Objects, LINQ to XML, LINQ to Entities, LINQ to SharePoint, LINQ to TerraServer, etc). Instead of using language operators or type-safe lambda extension methods to construct your LINQ queries, the dynamic query library provides you with string based extension methods that you can pass any string expression into.

Và bằng cách này, thậm chí còn nghĩ rằng question là không chính xác giống hệt nhau, các answer là khá nhiều như nhau.

+0

* an * câu trả lời; không có câu trả lời * ở đây. –

+0

@Marc Gravell: không chắc chắn nếu tôi chỉ bỏ lỡ một trò đùa hay một thứ gì đó (tiếng Anh không phải là ngôn ngữ mẹ đẻ của tôi), nhưng tôi liên kết với * a * câu trả lời cụ thể, và tôi không thể thấy điều gì sai khi nói đến câu trả lời _the_ (như trong _the_ câu trả lời mà tôi liên kết với) ... – Nailuj

+0

Tôi đọc nó như là "câu trả lời cho loại câu hỏi", nơi "the" (là số ít, bài báo xác định) đề cập đến "chỉ có thể, sane, hợp lý trả lời cho loại câu hỏi này ". Nó không quan trọng, nhưng về ngôn ngữ, có lẽ "cái này" sẽ rõ ràng hơn "cái". –

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