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操作的接口是不能修改的,这就要求我们必须实现以下操作:
- 获取entity的Id值
- 构造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);
}
参考资料
用到的工具
之前都是直接使用lambda表示,而且用的还很Happy,今天遇到的问题,让我很傻眼,基础还得巩固啊。今天也是第一次调试lambda表达式,用到了Expression Tree Visualizer for VS 2010这个小工具。在项目调试过程中可以比较直观的查看编译好的lambda表达式。
安装和使用方法,请参见:在Visual Studio 2010设置Expression Tree Visualizer
C#在泛型类中,通过表达式树构造lambda表达式的更多相关文章
- lintcode :前序遍历和中序遍历树构造二叉树
解题 前序遍历和中序遍历树构造二叉树 根据前序遍历和中序遍历树构造二叉树. 样例 给出中序遍历:[1,2,3]和前序遍历:[2,1,3]. 返回如下的树: 2 / \ 1 3 注意 你可以假设树中不存 ...
- LintCode-73.前序遍历和中序遍历树构造二叉树
前序遍历和中序遍历树构造二叉树 根据前序遍历和中序遍历树构造二叉树. 注意事项 你可以假设树中不存在相同数值的节点 样例 给出中序遍历:[1,2,3]和前序遍历:[2,1,3]. 返回如下的树: ...
- [leetcode/lintcode 题解] 前序遍历和中序遍历树构造二叉树
[题目描述] 根据前序遍历和中序遍历树构造二叉树. 在线评测地址: https://www.jiuzhang.com/solution/construct-binary-tree-from-preor ...
- .NET技术-6.0. Expression 表达式树 生成 Lambda
.NET技术-6.0. Expression 表达式树 生成 Lambda public static event Func<Student, bool> myevent; public ...
- 构造Lambda表达式
/// <summary> /// 构造Lambda表达式 /// </summary> /// <typeparam name="T">< ...
- C++11中新特性之:lambda 表达式
首先摆出Lambda表达式语法 lambda-expression: lambda-introducer lambda-declaratoropt compound-statementlambda-i ...
- C++11 中function和bind以及lambda 表达式的用法
关于std::function 的用法: 其实就可以理解成函数指针 1. 保存自由函数 void printA(int a) { cout<<a<<endl; } std:: ...
- C#中的委托,匿名方法和Lambda表达式
简介 在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=.答案是6个Firs ...
- (转)C#中的委托,匿名方法和Lambda表达式
简介 在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=5.答案是6个Fir ...
随机推荐
- PAT乙级 1012. 数字分类 (20)
1012. 数字分类 (20) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 给定一系列正整数,请按要求对数字进 ...
- Mysql 注意细节
1.无法连接远程数据库,是因为远程服务器并没有开通权限,提供给其他机子连接: 在服务器机子 开通权限: 1)进去MySql 2)mysql>GRANT ALL PRIVILEGES ...
- Win7旗舰版中的IIS配置asp.net的运行环境
Win7旗舰版中的IIS配置asp.net的运行环境 以前弄过好多次,都没有成功,昨天晚上不知怎么地就成功了,借用我同学的一句话,这叫“灵光一闪”,废话不多说了,这个成功是有图有视频有真相地哈! ...
- 《Focus On 3D Terrain Programming》中一段代码的注释一
取自<Focus On 3D Terrain Programming>中的一段: //--------------------------------------------------- ...
- git使用记录(新手入门)
最近参与了公司的项目开发,最后要用git来把代码添加到远程库,但是没怎么接触过git,记录一下使用的流程 首先,当然是先下载git,这个略过不提,下载完之后,在你想要保存代码的目录下,用git ini ...
- Android NDK 开发(三)--常见错误锦集合Log的使用【转】
转载请注明出处:http://blog.csdn.net/allen315410/article/details/41826511 Android NDK开发经常因某些因素会出现一些意想不到的错误, ...
- oracle 定时备份
第一步.bat脚本: @echo off echo 删除10天前的备分文件和日志 forfiles /p "z:/back" /m *.dmp /d -10 /c "cm ...
- 微信支付 APP 支付方式的服务器端处理程序
对于微信的APP的支付,客户服务说只能通过微信开放平台申请.后来在公众帐号确实发现了证据: 微信支付在申请的时候就比较严(麻烦),对服务类的一些支付,本来商品就是虚拟的,所以需要将商品描述的比较详细 ...
- PHP gmdate() 函数
定义和用法 gmdate() 函数格式化 GMT/UTC 日期/时间. 同 date() 函数 类似,不同的是返回的时间是格林威治标准时(GMT). 语法 gmdate(format,timestam ...
- 微信公众平台自定义菜单PHP开发
微信公众平台自定义菜单PHP开发,微信公众平台自定义菜单是如何实现的呢?其实很简单,首先在微信公众平台升级为服务号,获取appid和appsecret,然后根据这2个参数获取access_token, ...