自定义T4模板 - 首先从现有数据库为EF代码的ADO.Net实体数据模型

时间:2016-06-15 23:13:25

标签: c# entity-framework ado.net t4 odp.net

我正在尝试首先从现有数据库中找到并自定义EF代码的ADO.Net实体数据模型的T4模板。

我想要自定义或更改的是数据类型映射。我正在使用支持EF的Oracle的ODP.Net提供商。我正在尝试将Oracle数据类型编号重新映射到Int64而不是Decimal,因为我的要求。

由于我不熟悉编辑T4文件以进行自定义,因此我发现难以找到代码首先映射的模板文件。感谢任何指导我指向正确方向的帮助。enter image description here

1 个答案:

答案 0 :(得分:1)

2017年2月更新:您应该查看这个惊人的EntityFramework Reverse POCO Code First Generator项目,其中包含 T4模板,可以从现有数据库执行代码优先

这些模板非常易于使用,完全可自定义,我可以轻松地将自定义添加到这些模板中!更不用说它们比原始EF向导更完整。该项目的作者/贡献者非常友好和敏感,我自己做了一些贡献。

_

(事实证明我通过创建自己的T4模板重新发明了方形轮。)

原始答案(仅供参考,如果有人帮助任何人深入了解EF向导源代码):

我不知道为什么,但Model First的模板( EF Designer from database )很容易定制(但它们是基于EDMX的),而 Code First的代码来自数据库并不那么容易 - 即使您设法找到模板。

如果右键单击项目,单击“实体框架”和“自定义逆向工程师模板”,您将在文件夹Context.tt内获得Entity.ttMapping.ttCodeTemplates\ReverseEngineerCodeFirst但是,这些模板需要由一些外部调用者调用,这些调用者应该将一些上下文信息传递给模板 - 这就是为什么它们不能像Model First模板那样准备好进行自定义。

这些模板与您在Entity Framework source code(文件夹src\PowerTools\CodeTemplates\ReverseEngineerCodeFirst中)中找到的模板相同。在\src\PowerTools\Handlers\ReverseEngineerCodeFirstHandler.cs中,您将找到方法ReverseEngineerCodeFirst,它从数据库中读取元数据并传递给这些模板。该调用方法可以复制到自己的T4模板中(因此您不需要构建该Power Tools并在Visual Studio中安装),但它与Visual Studio和Project有一些交互,这很难做到使用普通的T4模板。

我基于上面提到的方法创建了一个T4 template,基本上是将ReverseEngineerCodeFirstHandler.cs所需的所有类/帮助器放在一起,并删除对Visual Studio DTE的引用。我的模板上有一些说明,但基本上你应该删除EF.Utility.CS.ttinclude的包含,并注释掉变量“var efHost”和“var code”

您在文件夹CodeTemplates\ReverseEngineerCodeFirst中找到的那些模板几乎相同与Code First From Database向导相同,除了一些细微差别:

  • 该向导会将一对多导航属性创建为HashSet<T>,而模板会将这些属性创建为List<T>
  • 该向导使用int?之类的无效内容,而另一个使用Nullable<int>
  • 该向导添加了一些代码分析抑制属性[SuppressMessage]
  • 向导将DbSets创建为虚拟,而模板则不创建。
  • 该向导使用数据注释(如[Table][Key][StringLength]等)以及DbContext.OnModelCreating内的其他部分(属性和关系)生成部分映射。 T4模板为每个实体(EntityTypeConfiguration<Entity>)生成配置类内的所有映射。

大多数差异都很容易调整,但我认为这并不重要。如果你想进行强大的自定义(就像我在模板上做的那样,包括自动推断不存在的关系,与视图的关系,类继承),我建议你创建自己的DTO(或POCO)来传递实体/属性/ NavigationProperties到包含的模板。在我的情况下,我使用原始的EdmMapping,将其映射到我的DTO,对这些DTO进行大量修改(基于我的公司标准),并将这些DTO传递给T4包括(经过小的修改)。< / p>