Създадох LINQ израз, който проектира последователност в нова последователност от анонимни типове, както намерих тук LINQ изразно дърво с анонимни типове.
Ето моя израз, който бих искал да изпълня:
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"].
Сега, това не е моят код, просто го коригирах малко, за да ми пасне. Това всъщност е последният изпълнен ред от код на фрагмента по-горе. Само за развиване на стека и компилиране.
Съжалявам, ако това може би няма смисъл. Ако имате нужда от разяснения, моля питайте.