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
据说看到好文章不推荐的人,服务器容易宕机!
本文版权归翟士丹(Stan Zhai)和博客园共有,原创文章,未经允许不得转载,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义