当前位置: 首页 > news >正文

一次修改闭源 Entity Provider 程序集以兼容新 EntityFramework 的过程

读完本文你会知道,如何在没有源码的情况下,直接修改一个 DLL 以去除 DLL 上的强命名限制,并在该程序集上直接添加你的“友元程序集(一种特殊的 Attribute,将它应用在程序集上,使得程序集内的 internal 类型能够被其它程序集直接调用)”。以此类推,你可以用此方法,直接修改程序集,达到想要的目的。

银行的一个项目,客户要求使用他们现有的的 Teradata 数据库,项目组第一个想到的是 NHibernate ,但是几乎没有找到关于 NHibernate 支持 Teradata 数据库的资料,于是把问题抛给了我。

我也没有找到相关资料,奇怪的是 Java 版 hibernate 是支持 Teradata 的,为什么 NHibernate 当年移植的时候没有做 Teradata dialect 的移植?是因为有技术上的限制吗?我一方面在 NHibernate 官方 Group 里表达了这个疑问,一方面发现 Entity Framework 是支持 Teradata 数据库的,把这个消息告知了项目组。

第二天,看到 NHibernate Group 里面有回复了,“或许只因为是没有人实现它”。这样我也打消了最后的顾虑,自己参考 Java 版 hibernate teradata dialect 做了个 NHibernate 版的实现,由于没有项目组 teradata 数据库的特定环境,只能发给项目组他们去做测试了。我之所以坚持使用 NHibernate ,是因为公司的框架有在 NHibernate 上的成熟封装,如果换用 EntityFramework ,需要做适配。

最后项目组决定用 EntityFramework ,但又希望使用最新版的 EntityFramework,却又发现最新版的 EntityFramework 6.1 对 Teradata 的支持存在问题,于是把问题抛给了我。

分析了一下,原因并不是 EntityFramework 不兼容 Teradata,EntityFramework 支持多数据库的原理是把数据库通用的地方抽象出来,然后去做不同数据库的实现(Entity Provider),有的数据库实现是 EntityFramework 官方提供的(如 SQL Server Entity Provider),Teradata 数据库官方提供了对 EntityFramework 的支持,但可能是由于后来 EntityFramework 做了改动,导致老的 Teradata Entity Provider 已经无法在 EntityFramework 6.1 上正常使用了,Teradata 官方也没有及时更新 Provider。

好了,抛开任何杂念,本着研究一下的态度,试一下吧:

Teradata for .NET涉及到的 dll

Teradata.Client.Provider.dll

Teradata 数据库的底层驱动。此程序集采用强命名。并对下面的 Teradata.Client.Entity.dll 友元(就是这个程序集里面的内部类对友元程序集可见,Teradata.Client.Provider.dll 里面的内部类对 Teradata.Client.Entity.dll 可见)。

Teradata.Client.Entity.dll

引用 Teradata.Client.Provider.dll 。Teradata 的 EntityFramework Provider,实现了 EntityFramework 规定的接口,这样 EntityFramework 就可以使用它操纵 Teradata 数据库。

Solution A:

试着在它原来的 Entity Provider 上包装一层,来兼容新版本的 EntityFramework , 实践证明行不通,虽然代码看上去差不多,但新版的 EntityFramework 将大量类的命名空间、程序集都改掉了,没有办法处理这些新老类型之间的转换。所以放弃了这个方案。

Solution B:

修改 Teradata.Client.Entity.dll (Entity Provider) 源代码来兼容新 EntityFramework 。

网上没有源码,通过反编译拿到了 Teradata.Client.Entity.dll 的 Source Code ,编译 Source Code 报了十几个错,不过还好都能够修正。最反编译出的代码已经没有错误了。

但是编译还是不通过,因为 Teradata.Client.Entity.dll 是 Teradata.Client.Provider.dll 的友元程序集,Teradata.Client.Entity.dll 直接引用了 Teradata.Client.Provider.dll 里面的内部类,而 Teradata.Client.Provider.dll 指定的友元程序集是强命名的 Teradata.Client.Entity.dll,反编译后的 Teradata.Client.Entity.dll 丢失了强命名,编译的时候不通过。

[图 Teradata.Client.Provider.dll 指定的友元程序集是强命名的 Teradata.Client.Entity.dll]

有两个解决办法:

1.反编译 Teradata.Client.Provider.dll ,拿到源码,去掉对 Teradata.Client.Entity.dll 的强命名友元,然后编译。(经尝试反编译后大量报错,放弃)

2.直接用工具修改 Teradata.Client.Provider.dll ,将里面对 Teradata.Client.Entity.dll 的强命名友元改为弱命名友元。

那么试二个办法:

1.在 Developer Command Prompt for VS2013 命令提示符中输入如下命令

:: 反编译 DLL 得到 IL

ildasm Teradata.Client.Provider.dll /output=i.il

打开找到里面的:

.assembly Teradata.Client.Provider

{

.custom instance void [mscorlib]System.Runtime.CompilerServices.InternalsVisibleToAttribute::.ctor(string) = (

01 00 81 62 54 65 72 61 64 61 74 61 2E 43 6C 69 // ...bTeradata.Cli

65 6E 74 2E 45 6E 74 69 74 79 2C 20 50 75 62 6C // ent.Entity, Publ

69 63 4B 65 79 3D 30 30 32 34 30 30 30 30 30 34 // icKey=0024000004

38 30 30 30 30 30 39 34 30 30 30 30 30 30 30 36 // 8000009400000006

30 32 30 30 30 30 30 30 32 34 30 30 30 30 35 32 // 0200000024000052

35 33 34 31 33 31 30 30 30 34 30 30 30 30 30 31 // 5341310004000001

30 30 30 31 30 30 63 39 66 63 62 31 62 35 33 36 // 000100c9fcb1b536

61 65 36 31 31 30 32 61 37 30 36 61 31 65 38 30 // ae61102a706a1e80

31 65 36 32 65 64 34 37 35 39 32 37 39 36 34 35 // 1e62ed4759279645

37 65 30 36 33 36 39 61 63 61 63 31 34 62 65 66 // 7e06369acac14bef

38 34 66 65 36 61 33 32 39 39 34 36 34 31 34 63 // 84fe6a329946414c

39 65 30 35 65 32 65 62 66 65 64 66 30 36 61 66 // 9e05e2ebfedf06af

33 66 39 36 32 37 36 64 34 32 31 35 32 38 30 37 // 3f96276d42152807

36 39 35 37 63 35 30 32 33 35 63 36 65 38 31 37 // 6957c50235c6e817

64 62 64 34 37 66 64 32 35 66 35 37 37 33 61 34 // dbd47fd25f5773a4

62 62 65 62 31 30 61 62 65 65 61 38 36 34 36 31 // bbeb10abeea86461

33 34 33 34 66 34 39 63 38 36 30 63 35 34 32 38 // 3434f49c860c5428

31 31 66 36 35 61 30 38 35 65 35 33 34 65 65 34 // 11f65a085e534ee4

34 38 37 33 37 31 33 31 61 37 64 38 62 31 33 63 // 48737131a7d8b13c

34 34 33 33 34 63 39 36 63 37 61 35 39 38 65 36 // 44334c96c7a598e6

65 65 36 38 65 63 61 66 64 34 66 37 63 61 31 33 // ee68ecafd4f7ca13

38 37 33 33 38 37 35 34 64 65 61 38 65 36 33 30 // 87338754dea8e630

31 61 66 65 63 38 00 00 ) // 1afec8..

…..

}

PublickKey 后面的就是强命名的 Public Key 了,用编辑器删掉它:

.custom instance void [mscorlib]System.Runtime.CompilerServices.InternalsVisibleToAttribute::.ctor(string) = (

01 00 16 54 65 72 61 64 61 74 61 2E 43 6C 69 65 // ...Teradata.Clie

6E 74 2E 45 6E 74 69 74 79 00 00 ) // nt.Entity..

这样 Teradata.Client.Provider.dll 对 Teradata.Client.Entity.dll 的友元就不是强命名的了。

然后接着在 Developer Command Prompt for VS2013 命令提示符中输入如下命令:

:: 将 IL 编译为 DLL

ilasm.exe i.il /DLL /OUTPUT=Teradata.Client.Provider.dll

[图 修改后]

这样 Teradata.Client.Entity.dll 就能编译通过了,这还不算完,还需要将 Teradata.Client.Entity.dll 里面的老的 EntityFramework Provider 实现修改为新实现(基本上批量替换一下命名空间就可以了)。

http://www.jsqmd.com/news/1117366/

相关文章:

  • 华硕笔记本性能调校革命:GHelper让你的设备重获新生
  • 163MusicLyrics:5分钟搞定全网音乐歌词,免费批量下载神器
  • Dify应用API安全加固实战:CORS、令牌与输入验证三大高危漏洞解析
  • KMR221与PIC18F85J50实现高精度电压检测方案
  • Claude Code 大规模封号背后:从账号风控、隐写检测到国产替代的底层逻辑
  • NanoClaw:轻量级本地智能体框架,纯离线运行的文档处理助手
  • 如何快速掌握CTFAK 2.0:Clickteam Fusion游戏资源提取完全指南
  • 杭州商业IP打造,实际效果如何?
  • MuleSoft+LLM企业级AI编排实战:打通大模型与核心系统
  • M95M04与PIC18F4455的SPI EEPROM存储方案设计
  • 3个ExplorerPatcher部署故障的深度诊断与实战解决方案
  • 如何快速掌握DevToysMac:开发者的终极效率提升指南
  • Three.js 阵列模型教程
  • 实战指南:如何用OpenCore Legacy Patcher让老旧Mac焕发新生,升级到最新macOS系统
  • 智能驾驶与自动驾驶的本质区别:责任边界、失效应对与量产可靠性
  • 显卡驱动装不上一直失败怎么处理?分步排查方法
  • AD5593R与PIC24F16KA102硬件协同设计与优化实践
  • LENA-R8与STM32F427ZI构建全球连接与高精度定位系统
  • 74HC32与PIC18F26K20实现高效键盘管理系统
  • 构建自动化SRC漏洞挖掘平台:Xray与Burp Suite的工程化整合实践
  • 基于Qwen3-32B与OpenClaw的AI驱动接口自动化测试实践
  • DeepChem分子指纹终极指南:ECFP与FCFP如何选择?新手必看!
  • Barrier终极指南:一套键盘鼠标控制多台电脑的完整教程
  • Three.js 顶点颜色教程
  • 【仅限首批内测者开放】AI原生开发流程SOP v3.2(含Git提交规范/AI生成代码审计checklist/责任追溯机制)——来自20年技术委员会的强制落地建议
  • 鸿蒙原生 ArkTS 布局深度解析:Swiper 无限循环 —— 首尾无缝衔接的实现与原理
  • 【AI工具组合黄金法则】:20年实战验证的7步工作流重构法,效率提升300%的私密框架
  • 小红书内容采集神器:XHS-Downloader批量下载工具完全指南
  • 十堰网红火锅实测测评|科学避坑就餐选型指南
  • 通往AGI的具身之路——TVA自适应协同进化系统(5)