使用 Lambda 表达式从字段名称中选择不同的字段

发布于 2024-10-03 03:23:24 字数 1326 浏览 1 评论 0原文

我需要从数据库表中获取两个字段(使用 linq-to-sql 检索),一个字段是日期时间(并且是固定字段),另一个字段始终是小数,但该字段可以不同。

该表保存每天以不同货币处理两次的货币数据,因此可能具有 AM_USD、PM_USD、AM_EUR 等字段。我需要获取数据,例如针对 PM_USD 的日期或针对 AM_EUR 的日期列表。

例如,我希望能够使用 lambda 表达式调用数据(这是一个精简的示例):

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

我一直在尝试编写一个函数来执行此操作,但失败了。

我管理的最接近的是:

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();
}

失败并显示“System.InvalidOperationException:Lambda 参数不在范围内”。

我确信我错过了一些明显的事情,或者以错误的方式进行。

有什么想法吗?

谢谢 时间

I need to get two fields from a database table (retrieved using linq-to-sql), one field is a datetime (and is a fixed field) and the other is always a decimal, but the field can be different.

The table holds currency data which is processed twice a day and in different currencies so could have fields such as AM_USD, PM_USD, AM_EUR etc. And I need to get data such as a list of the date against PM_USD or the date against AM_EUR.

I would like to be able to call the data using a lambda expression for example (this is a stripped out example):

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

I have been trying to write a function to do this, and am failing dismally.

The closest I have managed is:

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();
}

Which fails with "System.InvalidOperationException: Lambda Parameter not in scope".

I'm sure I missing something obvious, or going about it wrong way.

Any ideas?

Thanks
T

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

木落 2024-10-10 03:23:24

x.Foox(属性或字段)的成员,而不是参数:

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();
}

x.Foo is a member of x (property or field), not a parameter:

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();
}
被翻牌 2024-10-10 03:23:24

根据您的问题:

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

可以使用 LINQ 动态查询库

您可以使用 DynamicQuery 库
针对任何 LINQ 数据提供者
(包括 LINQ to SQL、LINQ to
对象、LINQ to XML、LINQ to
实体、LINQ to SharePoint、LINQ to
TerraServer 等)。而不是使用
语言运算符或类型安全 lambda
扩展方法来构建你的
LINQ查询,动态查询
库为您提供基于字符串的
您可以传递的扩展方法
任何字符串表达式。

顺便说一句,即使认为问题是不完全相同,答案 几乎是一样的。

From your question:

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

Specifying the field name in a LINQ query as a string can be done by using 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.

And by the way, even thought the question isn't exactly identical, the answer is pretty much the same.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文