EF 학습노트 - 사용자 정의 솔리드 클래스 생성

EF를 사용하면 DataBase 모드를 사용하고 실체 클래스는 모두 데이터베이스의 정의에 따라 자동으로 생성되기 때문에 우리는 관여할 수 없을 것 같다.사용자 정의 실체 클래스를 만들려면 어떻게 해야 합니까?
생각은 다음과 같다.
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();  
                }  
            }  
        }  
    }  

이 템플릿 파일은 보기에 매우 복잡해 보이지만, 사실상 대부분은 자동으로 생성되고 복사되어 온 것이다. 나 자신은 사실 전혀 모른다.

좋은 웹페이지 즐겨찾기