Ссылка между представлением EF Designer и пользовательским шаблоном T4 - PullRequest
1 голос
/ 12 декабря 2011

Я настроил генерацию кода EF T4 после этих шагов . Все хорошо, но кажется, что это EF Designer, где вы видите таблицы как «сущности» и отображение между свойствами и столбцами в таблице. Мой код показывает изменения, которые я делаю в шаблоне T4, но дизайнер не делает. Кроме того, он не обновляет код, если я добавляю новую таблицу в конструктор. Я что-то упускаю?

Edit: Кастомизация, которую я сделал до сих пор, добавляет пользовательское свойство к каждому из сгенерированных объектов. Ниже приведен код Т4:

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. Если проблема заключается в том, как я пишу, укажите правильное направление, как мне добавить это пользовательское свойство.

1 Ответ

1 голос
/ 12 декабря 2011

Конструктор отображает XML edmx, а не код C #, который он генерирует.Так что вы можете изменять сгенерированный код ... но это не влияет на то, что отображает дизайнер.

Далее ... если вы попытаетесь переписать сам edmx XML с вашими настройками, чтобы он отображался вдизайнер, вы должны убедиться, что вы правильно сопоставили новое свойство в csdl, msl и ssdl, иначе edmx не будет проверяться.

Кстати, не так уж и страшно изменить edmx xmlиспользуя ваш шаблон T4 либо.Вот пример, который я написал, чтобы автоматически генерировать и обновлять 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);
}
#>
...