我在these steps之后定制了EF T4代码生成。一切都很好,但似乎在EF Designer视图中,您将表视为“实体”以及表中属性和列之间的映射。我的代码显示了我在T4模板中所做的更改,但设计师却没有。此外,如果我向设计器添加新表,它不会更新代码。有什么我想念的吗?
修改 到目前为止我所做的自定义是为每个生成的实体添加自定义属性。以下是T4代码:
region.Begin(GetResourceString("Template_RegionPrimitiveProperties"));
WriteLine("");
Write("\t");
WriteLine("[EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]");
Write("\t");
WriteLine("[DataMemberAttribute()]");
Write("\t");
WriteLine("public Guid OriginalId { get; set; }");
foreach (EdmProperty property in entity.Properties.Where(p => p.DeclaringType == entity && p.TypeUsage.EdmType is PrimitiveType))
所有“Write”和“WriteLine”调用都是我自己的。我知道这不是最好的方法,但我仍然掌握着T4。如果我写这篇文章的方式是问题,请指出我应该如何添加这个自定义属性的正确方向。
答案 0 :(得分:1)
设计器显示edmx XML,而不是它生成的C#代码。因此,您可能正在修改生成的代码......但这不会影响设计器显示的内容。
此外......如果您尝试使用自定义重写edmx XML本身以便它在设计器中显示,则必须确保在csdl,msl和ssdl中正确映射新属性,或者edmx不会验证。
顺便说一下,使用你的T4模板修改edmx xml并不是那么糟糕。这是我写的一个例子,用于在保存edmx的任何时候使用TPH(每个层次表)SSDL和MSL自动生成和更新edmx(使用Database Generation Power Pack中的一些模板)。它存在于我的实体代T4模板中,每当保存edmx时都会调用它。<#@ assembly name="System.Core" #>
<#@ assembly name="System.Xml" #>
<#@ assembly name="System.Xml.Linq" #>
<#@ assembly name="System.Data" #>
<#@ assembly name="System.Data.Entity" #>
<#@ assembly name="System.Data.Entity.Design" #>
<#@ assembly name="$(DevEnvDir)Microsoft.Data.Entity.Design.DatabaseGeneration.dll"#>
<#@ assembly name="$(ProjectDir)..\..\Dependencies\Microsoft.Data.Entity.Design.DatabaseGenerationToolkit.dll"#>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Data" #>
<#@ import namespace="System.Data.Common" #>
<#@ import namespace="System.Data.Entity.Design" #>
<#@ import namespace="System.Data.Metadata.Edm" #>
<#@ import namespace="System.Diagnostics" #>
<#@ import namespace="System.Globalization" #>
<#@ import namespace="Microsoft.Data.Entity.Design.DatabaseGeneration" #>
<#@ import namespace="Microsoft.Data.Entity.Design.DatabaseGenerationToolkit" #>
<#@ import namespace="System.Runtime.Remoting.Messaging" #>
<#@ import namespace="System.Text.RegularExpressions" #>
<#@ import namespace="Microsoft.VisualStudio.TextTemplating" #>
<#@ import namespace="System.IO" #>
<#@ template language="C#" debug="true" hostspecific="true" #>
<#@ include file="GenerateTSQL.Utility.ttinclude"#>
<#@ include file="GenerateEDM.Utility.ttinclude"#>
<#@ output extension = ".xml" #>
<#
string inputFile = @"Model.edmx";
inputFile = Host.ResolvePath(inputFile);
var ssdlTransformPath = Host.ResolvePath(@"GenerateSSDL_TPH.tt");
var mslTransformPath = Host.ResolvePath(@"GenerateMSL_TPH.tt");
var document = new XmlDocument();
document.PreserveWhitespace = true;
document.Load(inputFile);
var namespaceManager = new XmlNamespaceManager(document.NameTable);
namespaceManager.AddNamespace("edmx", "http://schemas.microsoft.com/ado/2008/10/edmx");
namespaceManager.AddNamespace("ssdl", "http://schemas.microsoft.com/ado/2009/02/edm/ssdl");
var schema = "model";
var schemaNode = document.SelectSingleNode("//edmx:DesignerProperty[@Name='DefaultDatabaseSchema']", namespaceManager);
if (schemaNode != null) schema = schemaNode.Attributes["Value"].Value;
var csdl = document.SelectSingleNode("//edmx:ConceptualModels", namespaceManager).InnerXml;
CallContext.SetData(EdmConstants.csdlInputName, csdl);
CallContext.SetData(EdmParameterBag.ParameterName.TargetVersion.ToString(), new Version("2.0.0.0"));
CallContext.SetData(EdmParameterBag.ParameterName.ProviderInvariantName.ToString(), "System.Data.SqlClient");
CallContext.SetData(EdmParameterBag.ParameterName.ProviderManifestToken.ToString(), "2005");
CallContext.SetData(EdmParameterBag.ParameterName.DatabaseSchemaName.ToString(), schema);
CallContext.SetData(EdmParameterBag.ParameterName.DatabaseName.ToString(), document.SelectSingleNode("//ssdl:EntityContainer", namespaceManager).Attributes["Name"].Value);
CallContext.SetData(EdmParameterBag.ParameterName.EdmxPath.ToString(), inputFile);
string ssdl = new Engine().ProcessTemplate(File.ReadAllText(ssdlTransformPath), Host);
var ssdlNode = document.SelectSingleNode("//edmx:StorageModels", namespaceManager);
ssdlNode.InnerXml = ssdl;
CallContext.SetData(EdmConstants.existingSsdlInputName, ssdl);
CallContext.SetData(EdmConstants.ssdlOutputName, ssdl);
string msl = new Engine().ProcessTemplate(File.ReadAllText(mslTransformPath), Host);
var mslNode = document.SelectSingleNode("//edmx:Mappings", namespaceManager);
mslNode.InnerXml = msl;
var isChanged = document.OuterXml != File.ReadAllText(inputFile);
if (isChanged)
{
document.Save(inputFile);
}
#>