ここで見つけた匿名型の新しいシーケンスにシーケンスを射影する LINQ 式を作成しましたLINQ expression tree with anonymous types。
実行したい式は次のとおりです。
Document doc = ....;
doc.AllStatements.Select(s => new { field = s.Amount });
これは括弧内のセレクターの実行時の表現です:
{t => new field;Decimal;() {field = t.Amount}}
そして、これは式全体の実行時表現です。
{System.Linq.Enumerable+<UnionIterator>d__88`1[SISTEM.Models.Statement].Select(t => new field;Decimal;() {field = t.Amount})}
デバッグ中に列挙しようとすると、次のようになります。
") expected"
このように複数のフィールドの匿名型を試してみると:
doc.AllStatements.Select(s => new { field = s.Amount, field2 = s.Account });
私はこれを得る:
{System.Linq.Enumerable+<UnionIterator>d__88`1[SISTEM.Models.Statement].Select(t => new field;Decimal;field1;Nullable`1;() {field = t.Amount, field1 = t.Account})}
実行時エラーは次のとおりです。
"Unexpected character '`'"
誰かがこれを解読するのを手伝ってくれますか?
アップデート:
これは私の実際の呼び出しです:
var res = Expressions.DoExpression(typeof(Document), doc, "AllStatements.Select(new field=Amount, field1=Account)");
ただし、DoExpressions 関数の背後には多くの解析式と LINQ 式があります (500 行程度のコード)。
更新 2:
まず、コードのスニペットを次に示します。
Dokument doc = db.Dokumenti.First(); // Proper document, entity object;
var res = Expressions.DoExpression(
typeof(Dokument),
doc,
"SviFinStavovi.Select(new id=Iznos, dsc=Opis)"
);
SviFinStavovi は Dokument のナビゲーション プロパティであり、Iznos と Opis は SviFinStavovi の基になる型のプロパティです。
ただし、これらの 2 行のコードは例外をスローしません。res を列挙しようとした場合にのみ、例外がスローされます。あなたは上記のものを持っています。
SviFinStavovi.Select(Iznos) を入れていれば、問題なく動作したはずです。
これは DoExpression です:
public static object DoExpression(Type t, object obj, string expression){
ParameterExpression pe = Expression.Parameter(obj.GetType(), "objekat");
Expression SelectExpr = Expressions.ResolveCompleteExpression(pe, expression.Prepare());
return Expression.Lambda(SelectExpr, pe).Compile().DynamicInvoke(obj);}
ResolveCompleteExpression は全体を解析します。
さて、これは私がこのサイト、上記のリンクから取得した機能であり、追加したものであり、問題を引き起こします。
public static Expression SelectDynamic(Expression expr, IEnumerable<string> fieldNames)
{
Type source = expr.Type.GetGenericArguments()[0];
Dictionary<string, PropertyInfo> sourceProperties = new Dictionary<string, PropertyInfo>();
foreach (string arg in fieldNames) sourceProperties.Add(arg.Split('=')[0].Trim(), source.GetProperty(arg.Split('=')[1].Trim()));
Type dynamicType = LinqRuntimeTypeBuilder.GetDynamicTypeWrapper(sourceProperties);
ParameterExpression sourceItem = Expression.Parameter(source, "t");
IEnumerable<MemberBinding> bindings = dynamicType.GetFields().Select(p => Expression.Bind(p, Expression.Property(sourceItem, sourceProperties[p.Name]))).OfType<MemberBinding>();
Expression selector = Expression.Lambda(Expression.MemberInit(
Expression.New(dynamicType.GetConstructor(Type.EmptyTypes)), bindings), sourceItem);
return Expression.Call(typeof(Queryable), "Select", new Type[] { source, dynamicType }, expr, selector);
}
この時点で、expr は (正しく) doc.SviFinStavovi を表し、フィールド名は ["id=Iznos"] ["dsc=Opis"] になります。
さて、これは私のコードではありません。私に合わせて少し調整しただけです。これは、上記のスニペットの実質的に最後に実行されたコード行です。スタックを巻き戻してコンパイルするだけです。
これが意味をなさない場合は申し訳ありません。説明が必要な場合は、お尋ねください。