2011-12-12 85 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