【问题标题】:C# Create Lambda Expression DynamicallyC# 动态创建 Lambda 表达式
【发布时间】:2018-10-10 09:27:18
【问题描述】:


我与 Dapper 一起工作,并尝试为内部连接创建自动映射方法。
这是模型的示例:

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; }
}

这是查询:

SELECT * FROM "PAGE" INNER JOIN "USER" ON "PAGE"."IdUserCreatedPage" = "USER"."IdUser"

如果我手动编写代码,我会这样写:

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();  
}

现在,我想要动态创建映射对象所需的Func&lt;TFirst, TSecond, TOut&gt;
有人能帮我吗?非常感谢。

附:我知道在这种情况下,动态创建它是没有意义的,但这只是所有自动映射项目的简单版本。

【问题讨论】:

  • 这是一个问答网站。如果您已解决,请添加并接受答案。将 [SOLVED] 放在论坛网站标题中的做法是因为这些网站不是为寻找问题的答案而设计的,就像这个网站一样。
  • @JonHanna 好的,我做到了!

标签: c# linq lambda expression func


【解决方案1】:

解决方案

我终于找到了做我想做的事的方法。
这是生成Func&lt;TFirst, TSecond, TOut&gt;的函数代码:

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();
}

这是“GetPage”方法:

public List<Page> GetPage(IDbConnection dbConnection, string sql)
{
    return (List<Page>)dbConnection.Query<Page, User, Page>(sql, 
        MappingDynamicFunc<Page, User>(),
        splitOn: "IdUser").ToList();  
}

【讨论】:

    【解决方案2】:

    看看 PredicateBuilder。 http://www.albahari.com/nutshell/predicatebuilder.aspx

    这是一些伪代码

    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();
    

    【讨论】:

      猜你喜欢
      • 2015-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多