防止 T4 模板删除现有文件
我想为 edmx 模型中的每个实体创建一个名为 {0}Validator.cs 的单独类文件(现在不关心其内容)。
这似乎有效,但我无法解决它以防止我的 T4 模板首先删除我的所有文件。我怎样才能摆脱这种行为?
我发现,如果我调用 fileManager.Process(true),validator.tt 文件下的所有文件都将被重新创建(我不希望这样)。
有什么想法吗? 谢谢!
<#@ template language="C#" debug="false" hostspecific="true"#>
//<#@ include file="EF.Utility.CS.ttinclude"#>
<#@output extension=".cs"#>
<#
CodeGenerationTools code = new CodeGenerationTools(this);
MetadataLoader loader = new MetadataLoader(this);
CodeRegion region = new CodeRegion(this, 1);
string inputFile =@"ServicesEntities.edmx";
EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
string namespaceName = code.VsNamespaceSuggestion();
EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);
// for test purposes only...
fileManager.Process(true);
// for each entity, create a xxxValidator.cs file
foreach (EntityType entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
{
string fileName = entity.Name + "Validator.cs";
string filePath = this.Host.TemplateFile.Substring(0,this.Host.TemplateFile.LastIndexOf(@"\"));
filePath = filePath + @"\" + fileName;
if(!File.Exists(filePath))
{
fileManager.StartNewFile(filePath);
#>
// the content of the validator class
public partial class <#=code.Escape(entity)#>
{
public bool ValidateModel()
{
// enter checkmethods here!!! again
return true;
}
}
<#
}
}
fileManager.Process(true);
#>
I want to create for each entity in my edmx-model a separate class file called {0}Validator.cs (do not care about its content by now).
This seems to work, but I can't work it out to prevent my T4 template from deleting all my files first. How can I get rid of this behavior?
What I found out is that if I call fileManager.Process(true), all the files under my validator.tt file will be recreated (and I don't want this).
Any ideas please?
Thanks!
<#@ template language="C#" debug="false" hostspecific="true"#>
//<#@ include file="EF.Utility.CS.ttinclude"#>
<#@output extension=".cs"#>
<#
CodeGenerationTools code = new CodeGenerationTools(this);
MetadataLoader loader = new MetadataLoader(this);
CodeRegion region = new CodeRegion(this, 1);
string inputFile =@"ServicesEntities.edmx";
EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
string namespaceName = code.VsNamespaceSuggestion();
EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);
// for test purposes only...
fileManager.Process(true);
// for each entity, create a xxxValidator.cs file
foreach (EntityType entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
{
string fileName = entity.Name + "Validator.cs";
string filePath = this.Host.TemplateFile.Substring(0,this.Host.TemplateFile.LastIndexOf(@"\"));
filePath = filePath + @"\" + fileName;
if(!File.Exists(filePath))
{
fileManager.StartNewFile(filePath);
#>
// the content of the validator class
public partial class <#=code.Escape(entity)#>
{
public bool ValidateModel()
{
// enter checkmethods here!!! again
return true;
}
}
<#
}
}
fileManager.Process(true);
#>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我的情况完全相同。我想生成用于数据注释的伙伴类。我不想将数据放入 edmx 文件并更改我的模板以根据 edmx 数据添加正确的注释。那会花太长时间。最简单的解决方案是生成一个伙伴类并设置它,这样它就不会每次都重新生成。在这种情况下,效率比 T4 类应始终重新生成的约定更重要。
戴恩·莫格里奇想出了一个聪明的方法来做到这一点。他检查该文件是否已经存在。如果是的话,他将其读入并按原样写回。如果没有,他将渲染他的模板。查看 DbContext Templates\IRepository.tt。
https://github.com/danemorgridge/efrepo
以下是相关部分。
I am in the exact same situation. I want to generate buddy classes for data annotation. I don't want to put data into the edmx file and alter my templates to add the correct annotations based on the edmx data. That would take too long. The easiest solution is to generate a buddy class and set it so it doesn't regenerate every time. In this case efficiency is more important than the convention that T4 classes should always be regenerated.
Dane Morgridge figured out a clever way to do this. He checks to see if the file already exists. If it does he reads it in and writes it back out the way it was. If it doesn't he renders his template. Check out DbContext Templates\IRepository.tt.
https://github.com/danemorgridge/efrepo
Here are the relevant sections.
有点晚了,但值得...如果您使用 T4Toolbox,您可以告诉引擎在触发生成并且文件已经存在时不要删除生成的文件:
http://t4toolbox.codeplex.com
A bit late, but for what it's worth... If your are using T4Toolbox you can tell the engine not to delete generated files if a generation is triggered and the file already exists:
http://t4toolbox.codeplex.com
不,你不能。 T4 模板每次被触发时都会生成代码并执行代码。在此之前,所有文件都会被删除。但你有什么问题吗?您的自定义代码应该放置在部分代码中,因此即使重新生成其他部分代码也没关系。
No, you can't. The T4 Templates generates the code each time they are triggered and perform the code. And before that all files get deleted. But what is your problem with that? You custom code should be placed in partials so it doesn't matter if the the other partial get's regenerated.
重新创建文件有什么问题? T4 生成代码,您不应触摸生成的代码。如果您使用 T4 模板只是为了创建具有某些名称的文件,那么您使用的是错误的。您可以创建真正的 T4 模板,它也会生成文件内容,或者您不应该使用 T4 模板并手动创建文件。
What's wrong with recreating files? T4 generates the code and you should not touch generated code. If you use T4 template just to create files with some names you are using it wrong. You can either create real T4 template which will generate content of your file as well or you should not use T4 template and create files manually.
对于创建元数据、服务和 ViewModel 类(我希望能够修改)的 T4 模板,我希望能够将新模板与现有模板合并,并为新实体创建任何新模板,因此我创建在调用 fileManager.StartNewFile 之前备份文件 (.BAK)...
然后在 fileManager.Process 之后,我使用 SourceGear 的 DiffMerge 合并 .BAK 文件和新文件...
工作得很好,因为 DiffMerge 是一个GUI应用程序,我可以在保存之前处理冲突等。
For T4 templates that create Metadata, Service and ViewModel classes (which I want to be able to modify), I wanted the ability to merge the new templates with the existing ones, as well as create any new ones for new Entities, so I create a backup of the file (.BAK) before calling fileManager.StartNewFile...
and then after fileManager.Process I merge the .BAK file and the new one using SourceGear's DiffMerge...
Works pretty well, and since DiffMerge is a GUI app, I can handle conflicts, etc. before saving.