2013-08-19 15 views
5

私は、動的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)"); 

また、動的linqを使用してプロパティをキャストするにはどうすればよいですか?

var q = b.AsQueryable().Select("((float)it.Item1)"); 
+0

'Enumerable.Select'メソッドで文字列を使用する構文は何ですか? –

+0

@Bob。このタグには次のように書かれています:dynamic-linq – xanatos

答えて

8

私はdynamic-linqがこれらのことを実行するのに十分ではないと言います。これらのタイプのDateTime

リストは明らかにされ、MathConvert、さまざまな基本型(intfloatstring、...)、GuidTimespan:それだけ与えられたオブジェクトのメソッドといくつかの特別なクラスを探しますファイルにilspy/reflectorを使用すると表示されます。それらはSystem.Linq.Dynamic.ExpressionParser.predefinedTypesにあります。

今、明らかに私が間違っているかもしれないが、これは動作します:.Select("Guid.NewGuid().ToString()").Cast<string>().ToArray()

が、それはそれは「正しい」リストであることは非常に可能性だということを示します。

あなたは今http://www.krizzcode.com/2012/01/extending-dynamiclinq-language.html

興味を持っている場合は、インテリジェントな男は、動的LINQのソースを取り、単にその配列を拡大するダイナミックLINQを変更する方法については、ここでの記事があります...しかし、ここではありませんインテリジェントな男性...欲しいプログラマだけがの血液血液しかし特に内臓

var type = typeof(DynamicQueryable).Assembly.GetType("System.Linq.Dynamic.ExpressionParser"); 

FieldInfo field = type.GetField("predefinedTypes", BindingFlags.Static | BindingFlags.NonPublic); 

Type[] predefinedTypes = (Type[])field.GetValue(null); 

Array.Resize(ref predefinedTypes, predefinedTypes.Length + 1); 
predefinedTypes[predefinedTypes.Length - 1] = typeof(A); // Your type 

field.SetValue(null, predefinedTypes); 

(最初の呼び出しの後に、これらのタイプのメソッド/プロパティがキャッシュされるため)動的LINQのへの最初の呼び出しの前に(あなたが欲しいタイプで)これを行う

説明:我々は追加するためにリフレクションを使用私たちのオブジェクトはこの "特別なリスト"になります。

+0

提案の可能性がある場合は答えの代わりに.... – andy

+1

@andy答えが不可能ですまだ回答がありません – xanatos

+0

ポインタのおかげで@xanatos – Magnus

0
var b = new[]{ a }; 

上記のアレイは、アレイの種類を知らないで、そしてそれは、タイプセーフではないのですか?それは整数値が(私は文字列値を考える)ではありませんので、

あなたの値は、バリアントデータタイプに割り当てられている、あなたはあなたのクラス・パラメータのデータ型が整数であるため)(convert.toint32する必要がある必要がありますあなたのクエリでこの値を取得するとき

重要なヒントがここに(太字)である

var b = new **int**[]{ a }; 

代わりのvar b = new[]{ a };

それを試してみてください:

No property or field 'xxx' exists in **type** 'xxx' 

と以前の議論のためにこれを見てください:

Dynamic Linq - no property or field exists in type 'datarow'

0

私は混同されるかもしれませんが、あなたのSelectの中の文字列を使用していることにより、あなたの構文は私のためにコンパイルされません。次の構文が有効です:

+1

'OPはdynamic-linqを使用しているので、あなたの選択はコンパイルされません 'http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part -1-using-linq-dynamic-query-library.aspx – I4V

+0

ああ私は混乱していました:) –

0

私のために、次の作品は:

var a = new Tuple<int, int>(1, 1); 
var b = new[] { a }; 
var q = b.AsQueryable().Select(it=>A.Test(it.Item1)); 
var q1 = b.AsQueryable().Select(it => Convert.ToInt32(it.Item1)); 
var q2 = b.AsQueryable().Select(it => (float) it.Item1); 
6

私はこの上の受け入れ答えがすでに存在している知っているが、それは私のために動作しませんでした。私は動的Linq 1.1.4を使用しています。

$.GetNewestRisk() == null 

GetNewestRisk()は、$で表されるオブジェクトのパブリックメソッドです。このエラーが発生しました "クエリの実行中にエラーが発生しました。タイプ 'Patient'のメソッドは(インデックス2に)アクセスできません"。

ソースコードには、カスタムプロバイダを割り当てることができるGlobalConfigオブジェクトがあります。カスタムプロバイダを割り当てることで、使用したいすべてのタイプを保持できます。ここではカスタムプロバイダのソースコードは次のとおりです。

public class CustomTypeProvider: IDynamicLinkCustomTypeProvider 
{ 
    public HashSet<Type> GetCustomTypes() 
    { 
     HashSet<Type> types = new HashSet<Type>(); 
     types.Add(typeof(Patient)); 
     types.Add(typeof(RiskFactorResult)); 
     types.Add(typeof(PatientLabResult)); 
     types.Add(typeof(PatientVital)); 
     return types; 
    } 
} 

ここで私はそれを使用しています方法です:

System.Linq.Dynamic.GlobalConfig.CustomTypeProvider = new CustomType(); 

私は表現の内のオブジェクトのメソッドを呼び出すことができる午前、この呼び出しを行った後。

+0

この答えをSystem.Linq.Dynamic.Coreに適合させることができました。同じインターフェースを持ちますが、カスタムタイプをグローバルに適用するのではなく、個々の式にタイプを指定できるParsingConfigもあります。 – Kent

関連する問題