C# Create Lambda Expression Dynamically
12,527
Solution 1
SOLUTION
Finally I find the way to do what I want.
This is the code of the function that Generate Func<TFirst, TSecond, TOut>
:
public static Func<TFirst, TSecond, TFirst> MappingDynamicFunc<TFirst, TSecond>()
{
ParameterExpression paramFirst = Expression.Parameter(typeof(TFirst), "paramFirst");
ParameterExpression paramSecond = Expression.Parameter(typeof(TSecond), "paramSecond");
MemberExpression memberExpression = Expression.PropertyOrField(paramFirst, "UserCreatedPage");
BinaryExpression assign = Expression.Assign(memberExpression, paramSecond);
LabelTarget labelTarget = Expression.Label(typeof(TFirst));
GotoExpression returnExpression = Expression.Return(labelTarget, paramFirst, typeof(TFirst));
LabelExpression labelExpression = Expression.Label(labelTarget, Expression.Default(typeof(TFirst)));
BlockExpression block = Expression.Block(
assign,
returnExpression,
labelExpression
);
return Expression.Lambda<Func<TFirst, TSecond, TFirst>>(block, new ParameterExpression[] { paramFirst, paramSecond }).Compile();
}
And this is the "GetPage" method:
public List<Page> GetPage(IDbConnection dbConnection, string sql)
{
return (List<Page>)dbConnection.Query<Page, User, Page>(sql,
MappingDynamicFunc<Page, User>(),
splitOn: "IdUser").ToList();
}
Solution 2
Take a look at PredicateBuilder. http://www.albahari.com/nutshell/predicatebuilder.aspx
Here is some pseudo code
var predicate = PredicateBuilder.True<SomeClass>();
if (SomeCondition)
{
var inner = PredicateBuilder.False<SomeClass>();
inner = inner.Or(p => p.Category == "WhatEver");
inner = inner.Or(p => p.Category == "");
predicate = predicate.And(inner);
}
...
var result = MyIEnumerable<SomeClass>.AsQueryable()
.Where(predicate)
.FirstOrDefault();
Author by
Fabrizio Pairone
Updated on June 04, 2022Comments
-
Fabrizio Pairone almost 2 years
I work with Dapper and I try to create auto-mapped method for inner join.
This is the example of the models:public class User { public long IdUser { get; set; } public string Email { get; set; } } public class Page { public long Id { get; set; } public string Name { get; set; } public long IdUserCreatedPage { get; set; } public User UserCreatedPage { get; set; } }
This is the query:
SELECT * FROM "PAGE" INNER JOIN "USER" ON "PAGE"."IdUserCreatedPage" = "USER"."IdUser"
if I write code mannualy I will write this:
public List<Page> GetPage(IDbConnection dbConnection, string sql) { return (List<Page>)dbConnection.Query<Page, User, Page>(sql, (Page p, User u) => { p.UserCreatedPage = u; return p; }, splitOn: "IdUser").ToList(); }
Now, what I want is create dynamically the
Func<TFirst, TSecond, TOut>
that I need for mapping the object.
Can someone help me? Thank you very much.
P.S. I know that in this case it does not make sense create it dynamically, but this it's only a simply version of all the project of auto-mapping.