EF 학습노트 - 사용자 정의 솔리드 클래스 생성
생각은 다음과 같다.
1. 우리가 사용자 정의로 생성한 실체류는 모두 부분류(partial)이고 목적은EF가 생성한 실체류를 확대하는 것이다.
2. 확장 부분, 미리 작성하여 템플릿에 자동 생성
3. 모든 실체 클래스를 확충한다.
구현 방법:
1. VS2012에 두 개의 플러그인을 설치한다.
**Devart T4 Editor: VS 。
T4 Toolbox: 。**
2, 새 폴더 T4, 템플릿 파일 저장
1) T4 Toolbox 템플릿 파일 EntityTemplate을 만듭니다.tt, 여러 개의 실체 클래스 파일을 생성하는 역할
코드는 다음과 같습니다.
<#+
//
// Copyright © . All Rights Reserved.
//
public class Entity : CSharpTemplate
{
private string _className;
public Entity(string className)
{
_className = className;
}
public override string TransformText()
{
base.TransformText();
#>
namespace testEF
{
public partial class #> : IEntity
{
public string _ID
{
get
{
return Id.ToString();
}
}
}
}
<#+
return this.GenerationEnvironment.ToString();
}
}
#>
2) T4 템플릿 파일 EntityOutput 만들기tt, 앞에 쓴 EntityTemplate를 호출합니다.tt, 실제 생성 각종 실체 클래스 파일
[csharp] view plaincopy CODE에서 코드 슬라이스를 보고 제 코드 슬라이스로 파생
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ include file="EF.Utility.CS.ttinclude"#>
<#@ include file="T4Toolbox.tt" #>
<#@ include file="EntityTemplate.tt" #>
<#
string curPath = Path.GetDirectoryName(Host.TemplateFile);
string destPath = Path.Combine(curPath, @"..\Partial");// Partial
if(!Directory.Exists(destPath))
{
Directory.CreateDirectory(destPath);
}
const string inputFile = @"..\ShowMe.edmx";
var textTransform = DynamicTextTransformation.Create(this);
var itemCollection = new EdmMetadataLoader(textTransform.Host, textTransform.Errors).CreateEdmItemCollection(inputFile);
foreach (var entity in GetItemsToGenerate(itemCollection))
{
// , ,
Entity template = new Entity(entity.Name);
string fileName = string.Format(@"{0}\{1}.cs", destPath, entity.Name);
template.Output.Encoding = Encoding.UTF8;
if(File.Exists(fileName))
{
File.Delete(fileName);
}
template.RenderToFile(fileName);
}
#>
<#+
/* EF , *.edmx\*.Context.tt。
,
*/
public class EdmMetadataLoader
{
private readonly IDynamicHost _host;
private readonly System.Collections.IList _errors;
public EdmMetadataLoader(IDynamicHost host, System.Collections.IList errors)
{
ArgumentNotNull(host, "host");
ArgumentNotNull(errors, "errors");
_host = host;
_errors = errors;
}
public IEnumerable CreateEdmItemCollection(string sourcePath)
{
ArgumentNotNull(sourcePath, "sourcePath");
if (!ValidateInputPath(sourcePath))
{
return new EdmItemCollection();
}
var schemaElement = LoadRootElement(_host.ResolvePath(sourcePath));
if (schemaElement != null)
{
using (var reader = schemaElement.CreateReader())
{
IList errors;
var itemCollection = MetadataItemCollectionFactory.CreateEdmItemCollection(new[] { reader }, out errors);
ProcessErrors(errors, sourcePath);
return itemCollection;
}
}
return new EdmItemCollection();
}
public string GetModelNamespace(string sourcePath)
{
ArgumentNotNull(sourcePath, "sourcePath");
if (!ValidateInputPath(sourcePath))
{
return string.Empty;
}
var model = LoadRootElement(_host.ResolvePath(sourcePath));
if (model == null)
{
return string.Empty;
}
var attribute = model.Attribute("Namespace");
return attribute != null ? attribute.Value : "";
}
private bool ValidateInputPath(string sourcePath)
{
if (sourcePath == "$" + "edmxInputFile" + "$")
{
_errors.Add(
new CompilerError(_host.TemplateFile ?? sourcePath, 0, 0, string.Empty,
GetResourceString("Template_ReplaceVsItemTemplateToken")));
return false;
}
return true;
}
public XElement LoadRootElement(string sourcePath)
{
ArgumentNotNull(sourcePath, "sourcePath");
var root = XElement.Load(sourcePath, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo);
return root.Elements()
.Where(e => e.Name.LocalName == "Runtime")
.Elements()
.Where(e => e.Name.LocalName == "ConceptualModels")
.Elements()
.Where(e => e.Name.LocalName == "Schema")
.FirstOrDefault()
?? root;
}
private void ProcessErrors(IEnumerable errors, string sourceFilePath)
{
foreach (var error in errors)
{
_errors.Add(
new CompilerError(
error.SchemaLocation ?? sourceFilePath,
error.Line,
error.Column,
error.ErrorCode.ToString(CultureInfo.InvariantCulture),
error.Message)
{
IsWarning = error.Severity == EdmSchemaErrorSeverity.Warning
});
}
}
public bool IsLazyLoadingEnabled(EntityContainer container)
{
string lazyLoadingAttributeValue;
var lazyLoadingAttributeName = MetadataConstants.EDM_ANNOTATION_09_02 + ":LazyLoadingEnabled";
bool isLazyLoading;
return !MetadataTools.TryGetStringMetadataPropertySetting(container, lazyLoadingAttributeName, out lazyLoadingAttributeValue)
|| !bool.TryParse(lazyLoadingAttributeValue, out isLazyLoading)
|| isLazyLoading;
}
}
public static void ArgumentNotNull(T arg, string name) where T : class
{
if (arg == null)
{
throw new ArgumentNullException(name);
}
}
private static readonly Lazy ResourceManager =
new Lazy(
() => new System.Resources.ResourceManager("System.Data.Entity.Design", typeof(MetadataItemCollectionFactory).Assembly), isThreadSafe: true);
public static string GetResourceString(string resourceName)
{
ArgumentNotNull(resourceName, "resourceName");
return ResourceManager.Value.GetString(resourceName, null);
}
private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName";
public IEnumerable GetItemsToGenerate(IEnumerable itemCollection) where T: EdmType
{
return itemCollection
.OfType()
.Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName))
.OrderBy(i => i.Name);
}
#>
다양한 엔티티 클래스 파일을 생성하는 방법은 간단합니다. 이 Entity Output만 저장하면 됩니다.tt 파일, 각종 실체 클래스 파일은 소리에 따라 생성되어 시원하다.
마지막으로 생성된 파일은 파란색 동그라미와 같다
엔티티 확장 클래스:
//
// This file was generated by T4 code generator EntityOutput.tt.
// Any changes made to this file manually will be lost next time the file is regenerated.
//
namespace testEF
{
public partial class Show : IEntity
{
public string _ID
{
get
{
return Id.ToString();
}
}
}
}
이 템플릿 파일은 보기에 매우 복잡해 보이지만, 사실상 대부분은 자동으로 생성되고 복사되어 온 것이다. 나 자신은 사실 전혀 모른다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
WebView2를 Visual Studio 2017 Express에서 사용할 수 있을 때까지Evergreen .Net Framework SDK 4.8 VisualStudio2017에서 NuGet을 사용하기 때문에 패키지 관리 방법을 packages.config 대신 PackageReference를 사용해야...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.