• C#在泛型类中,通过表达式树构造lambda表达式


    C#在泛型类中,通过表达式树构造lambda表达式

    场景

    最近对爬虫的数据库架构做调整,需要将数据迁移到MongoDB上去,需要重新实现一个针对MongoDB的Dao泛型类,好吧,动手开工,当实现删除操作的时候问题来了。

    我们的删除操作定义如下:void Delete(TEntity entity)。TEntity是我们的泛型类。

    而MongoDB官方驱动自带的删除操作是这样的:

    1
    2
    3
    
    // 假设数据模型为已定义的Article
    var query = Query<Article>.EQ(t => t.Id, id);
    coll.Remove(query);
    

    Dao操作的接口是不能修改的,这就要求我们必须实现以下操作:

    1. 获取entity的Id值
    2. 构造lambda表达式用于获取Id属性

    实现

    对于第1个好办,直接通过反射拿就可以了,至于第2个构造lambda表达式却不知该如何下手了。

    在网上查资料了解到C# Lambda表达式树允许我们像处理数据(比如读取,修改)一样来处理Lambda表达式。。这就有方向了,研究了一下表达式树的相关知识,历经坎坷终于将其实现。

    我用到的lambda表达式比较简单,也容易构造,代码中看注释应该就明白了,代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    
    /// <summary>
    /// 因为使用的Mongodb,每个数据模型必定包含Id属性,通过Id属性来删除实体
    /// </summary>
    /// <param name="entity"></param>
    public void Delete(TEntity entity)
    {
        var coll = _db.GetCollection<TEntity>(typeof(TEntity).Name);
        if (entity == null)
        {
            return;
        }
        ObjectId id = (ObjectId)typeof(TEntity).GetProperty("Id").GetValue(entity, null);
    
        // 通过表达式树构造lambda表达式{t => t.Id}
        // 构造调用目标t
        var target = Expression.Parameter(typeof(TEntity), "t");
        // 构造对t的属性Id的表达式
        MemberExpression bodyExp = Expression.Property(
            target,
            "Id");
    
        // 构造完整的lambda表达式
        Expression<Func<TEntity, ObjectId>> selector =
            Expression.Lambda<Func<TEntity, ObjectId>>(bodyExp, new [] { target });
    
        // 使用泛型前的语句: Query<Article>.EQ(t => t.Id, id);
        var query = Query<TEntity>.EQ(selector, id);
        coll.Remove(query);
    }
    

    参考资料

    1. C# Lambda表达式树浅谈
    2. C#教程:lambda表达式转换成表达式树

    用到的工具

    之前都是直接使用lambda表示,而且用的还很Happy,今天遇到的问题,让我很傻眼,基础还得巩固啊。今天也是第一次调试lambda表达式,用到了Expression Tree Visualizer for VS 2010这个小工具。在项目调试过程中可以比较直观的查看编译好的lambda表达式。

    安装和使用方法,请参见:在Visual Studio 2010设置Expression Tree Visualizer

  • 相关阅读:
    eclipse开发首选项
    html中怎么跨域访问
    如何自定义标签
    eclipse开发首选项
    eclipse开发一个文件向导
    eclipse开发一个文件向导
    JavaScript 操作IE菜单
    html中怎么跨域访问
    如何在没有安装 Python 的机器上运行 Python 程序
    Openstack Keystone V3 利用 curl 命令获取 token
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3506202.html
Copyright © 2020-2023  润新知