我尝试在动态linq select语句中调用一个函数,但我得到错误:
No property or field 'A' exists in type 'Tuple2'
示例代码:
void Main()
{
var a = new Tuple<int, int>(1,1);
var b = new[]{ a };
var q = b.AsQueryable().Select("A.Test(it.Item1)");
q.Dump();
}
public static class A
{
public static int Test(int i)
{
return i++;
}
}
我应该如何更改我的代码才能使其正常工作?
例如,如果我调用内置函数Convert.ToInt32
,它工作正常。
var q = b.AsQueryable().Select("Convert.ToInt32(it.Item1)");
另外,我如何使用动态链接转换属性?
var q = b.AsQueryable().Select("((float)it.Item1)");
8条答案
按热度按时间cig3rfwq1#
以下内容对我很有效:
0ejtzxu12#
我要说的是,
dynamic-linq
并不“足够强大”,它只在给定的对象和一些特殊的类中寻找方法:Math
、Convert
、各种基本类型(int
、float
、string
...)、Guid
、Timespan
、DateTime
如果你在文件上使用ilspy/reflector,这些类型的列表是清晰可见的。它们在
System.Linq.Dynamic.ExpressionParser.predefinedTypes
中。很明显我可能错了,但这是可行的:
.Select("Guid.NewGuid().ToString()").Cast<string>().ToArray()
表明这很可能是“正确”的列表。
如果您感兴趣,这里有一篇关于如何修改动态LINQ的文章http://www.krizzcode.com/2012/01/extending-dynamiclinq-language.html
现在,一个聪明的人会把动态链接的来源和简单地扩大数组...但这里没有聪明的人...只有程序员想要 * 血 ! 血 *,特别是**内脏 *!
在第一次调用Dynamic Linq之前执行此操作(使用所需的类型)(因为在第一次调用之后,这些类型的方法/属性将被缓存)
说明:我们使用反射将对象添加到这个“特殊列表”中。
ojsjcaue3#
我知道在这个问题上已经有一个公认的答案,但它对我不起作用。我使用的是Dynamic Linq 1.1.4。我想做这样的查询
其中GetNewestRisk()是由$表示的对象上的公共方法。我一直收到此错误“运行查询时出错,类型'Patient'上的方法不可访问(在索引2处)"。
我在源代码中发现了一个GlobalConfig对象,它允许分配一个自定义提供程序,该提供程序将保存您可能希望使用的所有类型。以下是自定义提供程序的源代码:
下面是我如何使用它:
在进行这个调用之后,我就可以调用表达式中对象的方法了。
pn9klfpd4#
@xanatos的答案对.Net Core版本不起作用.所以我在System.Dynamic.Linq.Core上找到了一些类似的相关的由@肯特的作者自己编写的测试库DynamicExpressionParserTests。
给定的
TestCustomTypeProvider
类允许您使用DynamicLinqType
类注解,这对解决此问题非常有用。要回答这个问题,您只需要定义类(确保使用DynamicLinqType进行注解):
如上所述添加customTypeProvider:
并使用带有可配置Select的ParsingConfig来调用它:
t0ybt7op5#
@阿曼德已经为这个问题提出了一个很好的解决方案,作为我唯一能找到的解决方案,我想为任何尝试同样方法的人补充一下。
标记为的类...
...在运行以下行时必须考虑:
在上面提供的解决方案中,这假定包含要计算的函数的类与代码当前所在的类位于同一个类上。如果要在所述类之外使用方法,则需要更改程序集。
与上面的解决方案没有任何变化,这只是为了向任何试图使用它的人澄清。
gajydyqb6#
至于Dynamic LINQ的当前版本 (1.2.19),您可能会遇到另一个异常:
要让DLINQ知道您的类型'A',您有两个选项:
1.使用您自己的自定义类型提供程序设置分析配置,您可以在其中直接指定类型“A”。
1.使用属性 [DynamicLinqType] 标记类型。如果该类型加载到当前域中(这是通常的情况),您不必再做任何事情,因为默认的自定义类型提供程序已经在当前AppDomain中扫描了标记为 [DynamicLinqType] 的类型。您必须执行类似于answer操作。
如果您想同时使用两种方法-第一种用于类型'A',第二种用于类型'B',该怎么办?在这种情况下,您只需将类型'A'与默认提供程序类型“合并”即可:
blmhpbnm7#
我可能会感到困惑,但是您在
Select
s中使用字符串的语法对我来说无法编译。下面的语法有效:06odsfpq8#
上面的数组是不知道什么类型的数组,而且不是类型安全的?
你的值是以变量数据类型赋值的,所以它不是整数值(我认为是字符串值),当你在查询中得到这个值时,必须需要convert.toint32(),因为你的类参数的数据类型是整数
你试试看
而不是
var b = new[]{ a };
重要提示如下(粗体):
请看前面的讨论:
Dynamic Linq - no property or field exists in type 'datarow'