我想为我的edmx-model中的每个实体创建一个名为{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);
#>
答案 0 :(得分:5)
我处于完全相同的情况。我想为数据注释生成好友类。我不想将数据放入edmx文件并更改我的模板以根据edmx数据添加正确的注释。这将花费太长时间。最简单的解决方案是生成一个伙伴类并设置它,使其不会每次都重新生成。在这种情况下,效率比应该始终重新生成T4类的约定更重要。
Dane Morgridge想出了一个聪明的方法来做到这一点。他检查文件是否已经存在。如果确实如此,他会将其读入并按原样将其写回。如果没有,他会渲染他的模板。查看DbContext Templates \ IRepository.tt。 https://github.com/danemorgridge/efrepo以下是相关章节。
string OutputFile(string filename)
{
using(StreamReader sr = new StreamReader(Path.Combine(GetCurrentDirectory(),filename)))
{
string contents = sr.ReadToEnd();
return contents;
}
}
if(!DoesFileExist(entity.Name + "Repository.cs"))
{
fileManager.StartNewFile(entity.Name + "Repository.cs");
}
else
{
fileManager.StartNewFile(entity.Name + "Repository.cs");
this.Write(OutputFile(entity.Name + "Repository.cs"));
}
答案 1 :(得分:2)
有点晚了,但值得一提......如果你正在使用T4Toolbox,你可以告诉引擎如果触发了一代并且文件已经存在,就不要删除生成的文件:
template.Output.PreserveExistingFile = true;
答案 2 :(得分:1)
答案 3 :(得分:0)
重新创建文件有什么问题? T4生成代码,您不应该触摸生成的代码。如果你只使用T4模板来创建一些名称错误的文件。您可以创建真实的T4模板,它也会生成文件的内容,或者您不应该使用T4模板并手动创建文件。
答案 4 :(得分:0)
对于创建元数据,服务和ViewModel类(我希望能够修改)的T4模板,我希望能够将新模板与现有模板合并,并为新实体创建任何新模板,所以我在调用fileManager.StartNewFile ...
之前创建了一个文件备份(.BAK) foreach (EntityType entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
{
var outputPath = Path.GetDirectoryName(Host.TemplateFile);
var outputFile = entity.Name + ".ViewModel.cs";
var fileName = Path.Combine(outputPath, outputFile);
if (File.Exists(fileName))
{
var newName = fileName + ".BAK";
File.Move(fileName, newName);
}
fileManager.StartNewFile(outputFile);
然后在fileManager.Process之后我使用SourceGear的DiffMerge合并.BAK文件和新文件......
fileManager.Process();
System.Diagnostics.Process p = new System.Diagnostics.Process();
foreach (EntityType entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
{
var outputPath = Path.GetDirectoryName(Host.TemplateFile);
var outputFile = entity.Name + ".ViewModel.cs";
var fileName = Path.Combine(outputPath, outputFile);
var newName = fileName + ".BAK";
if (File.Exists(newName))
{
String s = String.Format("-m -nosplash \"{0}\" \"{1}\" \"{2}\"", fileName, fileName, newName);
p.StartInfo.Arguments = s;
p.StartInfo.FileName = "C:\\Program Files (x86)\\SourceGear\\DiffMerge\\DiffMerge.exe";
p.StartInfo.Verb = "Open";
p.Start();
p.WaitForExit();
File.Delete(newName);
}
}
效果很好,因为DiffMerge是一个GUI应用程序,我可以在保存之前处理冲突等。