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 ...
随机推荐
- C++笔试题(部分)
1.简述C++11和Boost 2.struct和union与class的区别 3.为什么C++中调用被C编译器编译后的函数要加extern C声明? 4.以下代码哪里不对? #pragma regi ...
- imread函数、namedWindow函数、imshow函数、imwrite函数
1.imread函数 首先,我们看imread函数,可以在OpenCV官方文档中查到其原型如下: Mat imread(const string& filename, int flags=1 ...
- Swift 注释
注释就是对代码的解释和说明.目的是为了让别人和自己很容易看懂.为了让别人一看就知道这段代码是做什么用的. 正确的程序注释一般包括序言性注释和功能性注释.序言性注释的主要内容包括模块的接口.数据的描述和 ...
- 如何用javascript 的eval动态执行一个需要传对象参数的函数
代码如下: var method = 'setRiskItemAmount_'+id[1]+'(id[0],id[2],this.value);'; console.log(method); eval ...
- WKWebView与Js实战(OC版)
前言 上一篇专门讲解了WKWebView相关的所有类.代理的所有API.那么本篇讲些什么呢?当然是实战了! 本篇文章教大家如何使用WKWebView去实现常用的一些API操作.当然,也会有如何与JS交 ...
- 通达OA 免狗迁移到公网 的另类解决办法
1,通达OA 发布到公网 ,要真正的 Anywhere2,正版通达OA,有加密狗在本地机器上 ,通达必须检测有狗才可以运行3,阿里云服务器 (你想往上插加密狗都没地方的说..汗)4,本地ISP 不提 ...
- [已解决] java.lang.ClassNotFoundException: org.apache.jsp.WEB_002dINF.com.yourproject.test_jsp
同事遇到了一个问题,开始项目运行的好好的,过了一段时间再访问页面会报出如下错误信息(只贴了部分), 这是为啥呢,可能是由于servlet-api版本jar包重复导致的,他项目本身使用了servlet- ...
- 如何检查失败的Segment/master
在启用Mirror情况下,可能出现Segment失败时,系统不会中断服务,而且没有明确提示.检查系统状态的一种方法就是使用gpstate命令.该命令会列出GPDB系统中每个独立组件(Primary I ...
- java.lang.VerifyError异常
以前遇到过java.lang.VerifyError 原因是jar包冲突 tomcat6自带jsp.jar.servlet.jar所以项目中不用引入 tomcat5不带jsp.jar.servlet. ...
- js笔记----(运动)淡入淡出
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...