2011-12-12 36 views
0

我已经按照these steps自定义了EF T4代码生成。一切正常,但似乎是EF Designer视图,您可以在其中将表视为“实体”,并将表格中的属性与列之间的映射关系视为“实体”。我的代码显示了我在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)) 

所有的“写”和“的WriteLine”电话是我自己的。我知道这不是做这件事的最好方式,但我仍然得到了T4的窍门。如果我写这篇文章的方式是问题,请指出我应该如何添加此自定义属性的正确方向。

+0

您是如何定制的?即使在保存.edmx文件后它不会更新? – Shymep

+0

我用迄今为止添加的“代码”编辑了问题。 – FelixMM

+0

@ JeffN825说了正确的事情。你在表中的id列有什么问题你应该手动添加id属性? – Shymep

回答

1

设计人员显示edmx XML,而不是它生成的C#代码。所以你可能会修改生成的代码......但这并不影响设计者显示的内容。

进一步...如果您尝试用自定义重写edmx XML本身,以便它在设计器中显示,则必须确保在csdl,msl和ssdl中正确映射新属性,否则edmx将无法验证。

顺便说一句,用你的T4模板修改edmx xml也不是那么可怕。下面是我写的一个例子,用于在任何时候保存edmx(使用数据库生成电源包中的一些模板)时自动生成和更新带有TPH(每个层次的表格)的SSDL和MSL的edmx。它存在于我的实体生成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); 
} 
#> 
+0

感谢您的解释。 – FelixMM