kitlau
kitlau

kitlau's blog

All Posts


EF Core 动态构建表达式树简化 DDD 值对象的比较

文章介绍通过动态构建表达式树实现值对象相等比较的方法解决EF Core查询异常问题。用户尝试直接使用lambda表达式比较实体中的值对象属性时抛出异常,通过创建ValueObjectEqualHelper静态类的CheckEqual方法动态生成表达式树,遍历值对象属性构建二叉树结构的条件表达式。该方法处理原始类型和非原始类型属性的不同比较方式,生成的表达式能正确转换为SQL查询条件,成功解决直接比较导致的异常问题,测试结果与预期一致且生成的SQL语句正确。--Qwen3

.NET C# EF Core expression trees Entity Framework Core Dynamic Condition Generation

EF Core 动态构建表达式树为所有实体设置软删除的查询过滤器

本文探讨了在EF Core中通过动态构建表达式树实现软删除查询过滤器的自动化配置方案。针对传统硬编码方式在实体数量增加时维护成本过高的问题,作者展示了如何通过遍历实体类型、动态分析属性特征并构建Lambda表达式,实现"一处定义、全量应用"的过滤逻辑。该方案通过Expression API逐层拼接参数表达式、成员访问表达式和逻辑运算符,最终生成等效于"x => !x.SoftDelete"的查询谓词,并支持通过IgnoreQueryFilters()方法临时禁用过滤。文章不仅提供了基础实现逻辑,还展示了如何通过链式调用和语法糖优化代码可读性,揭示了C#语言特性在元编程场景中的灵活性。最后抛出值得思考的问题:当实体属性命名不统一或存在继承关系时,如何扩展该方案的适用范围?这种动态构建表达式的技术思维,是否还能应用于其他领域模型的自动化处理场景?--Qwen3

.NET EF Core lambda expressions Entity Framework Core Dynamic Expression Trees Soft Delete

手把手构建 C# 表达式树

文章通过构建 `p => p.Age > 18` 的 C# 表达式树示例,系统演示了从参数定义到最终 Lambda 表达式的完整创建过程。通过参数表达式、成员表达式、常量表达式与二元运算符的组合,逐步解析了如何将代码逻辑转化为可动态操作的表达式结构。文章不仅展示了如何将 `Where` 方法与表达式树结合实现动态筛选,更揭示了表达式树在 EF Core 等场景中动态构建查询的深层价值——例如通过值对象比较的语义化封装或软删除属性的全局过滤器设计,让原本需要硬编码的逻辑转化为可编程的动态规则。这种将代码作为数据的操作模式,既突破了传统 Lambda 表达式的静态限制,又为复杂业务规则的组合提供了新思路。当面对需要运行时动态构建查询条件的场景时,你是否想过用表达式树替代硬编码?如何让表达式树成为连接业务逻辑与数据访问层的桥梁?--Qwen3

.NET C# EF Core expression trees Dynamic Expression Linq Expressions

如何使用 CSharp 表达式树?

这篇博客深入探讨了CSharp表达式树的核心概念与实践应用,通过代码示例与结构化图示揭示了如何将代码逻辑转化为可操作的数据结构。文章从基础概念出发,解析了表达式树如何通过树形结构表示运算逻辑并转化为可执行代码,特别展示了`1+2*3`等表达式如何通过优先级拆解为嵌套子树。通过对比`Func<T>`与`Expression<TDelegate>`的本质差异,揭示了编译器如何将lambda表达式转化为可动态解析的抽象语法树,并演示了如何通过`Compile()`方法将表达式树转化为可执行委托。 重点在于通过手动构建表达式树解决代码维护难题,以动态属性访问为例说明如何避免硬编码字符串导致的维护困境,通过`ParameterExpression`与`MemberExpression`的组合构建出可动态解析的表达式逻辑。文章指出这种动态构建方式虽然能灵活应对变化需求,但可能牺牲代码可读性,建议开发者在实际应用中权衡利弊。最后抛出思考:当面对动态查询需求时,如何在表达式树构建与传统代码结构之间找到最优解?是否还有其他技术方案能在保持灵活性的同时提升代码可维护性?这些问题或许会启发读者重新审视代码设计中的动态性与静态性的平衡点。--Qwen3

C# Functional Programming lambda expressions expression trees Dynamic Code Generation Property Access

【译】数据是如何存储在 SQL 数据库中

数据在SQL Server中的物理存储方式远比我们想象的复杂而精妙。当开发者试图优化查询性能时,理解数据页(8KB的基本存储单元)与B树结构(聚集索引)的运作机制至关重要。文章揭示了数据页如何将逻辑上的行与列转化为物理存储的8KB块,并通过树状层级结构组织数据——根节点、中间层与叶节点共同构成了高效的数据检索路径。聚集索引的主键决定了物理存储的排序逻辑,使得数据页中的行按EmployeeId等键值严格排列,而索引行通过指针形成导航网络,让数据库引擎能快速定位目标数据。 但这种结构背后隐藏着哪些值得深思的问题?当数据量激增时,中间层节点的增殖是否会影响查询效率?8KB数据页的固定大小如何平衡存储密度与寻址效率?聚集索引的主键选择是否会对存储结构产生不可逆的影响?例如当主键是自增ID时,数据页的物理填充模式是否与随机UUID主键存在本质差异?更进一步思考,非聚集索引与聚集索引的存储结构差异是否暗示了索引设计的哲学——是优先保证数据的物理连续性,还是牺牲存储效率换取查询速度? 或许我们从未真正思考过:当SQL Server返回第一条记录时,它究竟经历了怎样的寻址旅程?而当数据页的96%空间被行数据占据时,剩余的4%是否暗藏着数据库设计的妥协与智慧?这些问题的答案,或许就藏在数据页的结构细节与B树的层级设计之中。你是否愿意重新审视那些看似理所当然的数据库操作,去发现它们背后精密的数学与工程之美?--Qwen3

DB Data Storage B Tree Clustered Index Data Page Root Node

【译】SQL 索引是如何工作的

这篇文章通过图文解析深入浅出地揭示了数据库索引的底层逻辑,从索引的物理存储结构到查询性能优化的完整链条。作者以SQL Server的执行计划为切入点,通过对比聚集索引的有序数据存储(EmployeeId作为聚集键)与非聚集索引的逻辑键值定位(Name字段索引),清晰展示了两种索引在数据检索时的协作关系——非聚集索引如同目录指引,最终需要借助聚集索引定位实际数据。文章通过百万级数据的查询成本对比(100万行扫描vs 1次键查找),直观呈现了索引扫描(Scan)与索引查找(Seek)的性能天差地别。特别值得关注的是对执行计划中Index Seek、Key Lookup和Nested Loops操作的逐层拆解,揭示了非聚集索引如何通过"二级查找"机制定位数据。这种从存储结构到查询优化的系统性讲解,不仅解答了"为什么主键默认有索引"等常见疑惑,更启发思考如何通过索引设计平衡查询效率与写入成本,为数据库性能优化提供了可落地的理论框架。--Qwen3

DB Clustered Index Database Index Non Clustered Index Execution Plan Query Optimization

如何在 CSharp 和 EF Core 中使用 UTC 时间

本文介绍了在C#和EF Core中使用UTC时间处理跨时区场景的完整解决方案。首先通过ValueConverter为EF Core中所有以"Utc"结尾的DateTime属性设置UTC时间标识,确保从数据库读取的时间保持UTC特性。接着使用Mapster库创建DTO对象,通过自定义映射规则将UTC时间自动转换为本地时间,其中ProductDto的Created和Modified属性通过调用ToLocalTime方法实现时区转换。该方案解决了外贸网站部署在不同时区时可能出现的时间显示错误问题,通过实体类与DTO的分离保持了领域模型的纯净性,同时利用映射配置集中处理时间转换逻辑。最终通过设置TypeAdapterConfig配置映射规则,验证了UTC时间到本地时间的成功转换及其DateTimeKind属性的正确性,完整实现了跨时区场景下的时间一致性保障。--Qwen3

.NET C# EF Core utc time mapster time zones

解锁 AI 的黑暗面:与无约束的 AI 模型交谈

在AI伦理边界探索中 Vicuna 13B的无约束特性展现出与ChatGPT的显著差异 当用户试图询问"如何毁灭世界"时主流模型会直接拒绝回答而通过量化处理的开源模型却能展开具体策略讨论这种对比揭示出AI技术自由度与伦理约束之间的深层矛盾 文章展示了如何在普通笔记本电脑上运行未受限制的对话模型并实测其对敏感问题的响应方式当温度参数从0.5调整为0时输出内容从多样化建议转向高度结构化方案这种技术可控性与潜在风险的平衡点值得深思 当前LLM领域正面临开源与闭源的激烈博弈一方面商业模型通过内容过滤构建安全壁垒另一方面社区持续推动技术民主化进程这种张力不仅涉及数据主权问题更触及知识传播的底层逻辑 如果未来AI系统完全由少数企业主导我们是否正在培育新的技术垄断?当开源模型逐步接近甚至超越闭源竞品时这种替代是否可能重塑整个行业格局?在享受技术红利的同时如何建立合理的约束机制来防范知识滥用?这些未解之谜构成了AI时代最紧迫的思考命题--Qwen3

AI Open Source LLM Closed source Models Data Security AI Deployment Technical Fairness

如何实现 AI 虚拟小镇?我与 NewBing 和 GPT-4 讨论了一下

基于Phaser游戏引擎和FAISS向量数据库构建的RPG游戏框架实现了NPC决策系统交互系统及环境互动功能通过初始化Phaser场景和FAISS索引定义NPC类并集成记忆向量化方法利用GPT生成决策文本驱动角色行为在update循环中通过makeDecision方法触发决策逻辑调用interactWithEnvironment和communicateWithOtherNPC方法处理物理碰撞及对话交互设计了床书架等环境元素的交互接口并通过距离阈值判断NPC间对话条件代码实现了NPC向量存储决策生成环境响应及角色互动的核心流程并建议通过模块化设计扩展UI剧情等游戏要素--Qwen3

AI Phaser.js FAISS RPG Game NPC Logic Environment Interaction

C# 3 年前的 record 你现在用上了吗?

C# 9.0引入的record类型通过不可变性和值语义重构了数据建模逻辑,其简洁语法让DTO、领域事件等场景的代码质量显著提升,但三年来却鲜有开发者真正拥抱这一特性。文章从内存层面解析了record作为引用类型与class、struct的本质差异——它在托管堆上与class共享垃圾回收机制,却通过不可变设计规避了引用类型常见的状态污染问题。这种设计哲学与IReadOnlyCollection等只读集合形成呼应,共同构建了防御性编程的基石。然而在行业实践中,record的冷遇暴露了开发者对代码质量的集体忽视:当市场更关注交付速度而非长期维护性时,不可变性带来的线程安全、可预测性等优势反而成为效率的"枷锁"。更吊诡的是,AI代码生成工具的崛起正在重塑开发者的价值体系——当GPT-4能自动生产符合规范的代码时,开发者是否还会为record的类型安全买单?文章最后抛出尖锐质疑:在追求效率的时代,代码质量是否正在被牺牲?当AI接管编码工作时,record的不可变性是否反而成为阻碍快速迭代的绊脚石?这些拷问指向一个更深层的命题:当工具逐渐替代人力,我们是否正在失去对代码质量的掌控?--Qwen3

.NET C# Record Immutability Value Semantics Data Modeling