2011-04-30 4 views
3

내 MVC 프로그램에서 내 모델에 대한 DataAnnotations를 쓰고 있습니다. 세 번째 모델에 대해서도 똑같은 작업을 수행 한 후에는이 작업을 수행하는 더 쉬운 방법이 있는지 궁금합니다.DataAnnotations 용 비주얼 편집기 ASP.NET MVC?

[MetadataType(typeof(ArticleMD))] 
public partial class Article 
{ 
    public class ArticleMD 
    { 
     [DisplayName("Created By:")] 
     public string CreatedBy { get; set; } 

     [DisplayName("Additional Information:")] 
     [DataType(DataType.MultilineText)] 
     public string AdditionalInformation { get; set; } 

     [DisplayName("Title:")] 
     [Required] 
     public string Title { get; set; } 
//... 

사람이 당신이 모델이나 뷰 모델을 선택하고 (별도의 메타 데이터 클래스에서)이 물건을 모두 정의하는 GUI를 사용할 수 있도록 할 비주얼 스튜디오에 대한 애드온 또는 플러그인을 알고 있나요?

+0

GUI 도구로 더 빨리 만들 수 있다고 상상할 수는 없습니다. 당신은 T4와 함께 더 운이 좋을지도 모릅니다. – R0MANARMY

답변

0

oss 또는 타사 추가 기능이 아직 제공되지 않는다고 생각됩니다.

1

저는 GUI 편집기를 모르지만 T4 템플릿을 사용하여 각 메타 데이터 클래스의 시작을 생성합니다. post에서 아이디어를 얻었습니다. Dan Wahlin.

<# 
//  Created by Dan Wahlin - http://www.thewahlingroup.com 
//  Title: T4 Metadata and Data Annotations template 
//  Usage: Generates the initial "buddy" classes to handle data validation across multiple frameworks 
//  Description: I got tired of writing my initial "buddy" classes by hand once my EF model was created. This template 
//     handles generating all the classes and generates the primitive and navigation properties. It also 
//     decorates the properties with the [Required] and [StringLength] attributes as appropriate. Once the 
//     template generates the code you can copy it to a new file and make all the tweaks you want to support 
//     custom data annotations. 
//  License: UIFAYW - Use it for anything you want (free or commercial) 
//  Made enhancements? Please let me know at dwahlin at xmlforasp dot net 
//  To use: 
//    1. Add the file into your project (it needs a .tt extension) 
//    2. Change the Source CsdlPath to point to your Entity Framework 4 .edmx file 
//    3. Whatever you name the .tt file will also be the name given to the code file it generates 
//    4. Don't make changes directly to the modified code. You'll need to copy it to a file 
//     you control or else the template may overwrite changes you make. 

#> 
<#@ template language="C#" debug="false" hostspecific="true"#> 
<#@ import namespace="System.Text.RegularExpressions" #> 
<#@ include file="EF.Utility.CS.ttinclude"#><#@ output extension=".cs"#><# 

UserSettings userSettings = 
     new UserSettings 
     { 
      SourceCsdlPath = @"YourModel.edmx", 
      ReferenceCsdlPaths = new string[] {}, 
      FullyQualifySystemTypes = true, 
      CreateContextAddToMethods = true, 
      CamelCaseFields = false, 
     }; 

ApplyUserSettings(userSettings); 
if(Errors.HasErrors) 
{ 
    return String.Empty; 
} 

MetadataLoader loader = new MetadataLoader(this); 
MetadataTools ef = new MetadataTools(this); 
CodeRegion region = new CodeRegion(this); 
CodeGenerationTools code = new CodeGenerationTools(this){FullyQualifySystemTypes = userSettings.FullyQualifySystemTypes, CamelCaseFields = userSettings.CamelCaseFields}; 

ItemCollection = loader.CreateEdmItemCollection(SourceCsdlPath, ReferenceCsdlPaths.ToArray()); 
ModelNamespace = loader.GetModelNamespace(SourceCsdlPath); 
string namespaceName = code.VsNamespaceSuggestion(); 
UpdateObjectNamespaceMap(namespaceName); 

#> 

using System; 
using System.ComponentModel; 
using System.ComponentModel.DataAnnotations; 
using System.Data.Objects.DataClasses; 
/* 
namespace <#=namespaceName#> 
{ 
    <# 
     foreach (EntityType entity in GetSourceSchemaTypes<EntityType>().OrderBy(e => e.Name)) 
     { 
    #> 
[MetadataType(typeof(<#=code.Escape(entity)#>Metadata))] 
    <#=Accessibility.ForType(entity)#> <#=code.SpaceAfter(code.AbstractOption(entity))#>partial class <#=code.Escape(entity)#> 
    { 
     internal sealed class <#=code.Escape(entity)#>Metadata 
     { 
     <# 
      bool first = true; 
      foreach (EdmProperty property in entity.Properties.Where(p => p.DeclaringType == entity && p.TypeUsage.EdmType is PrimitiveType)) 
      { 
       if (first) 
       { 
        WriteLine(string.Empty); 
        first = false; 
       } 
       WritePrimitiveTypeProperty(property, code); 
      } 
      foreach (NavigationProperty navProperty in entity.NavigationProperties.Where(n => n.DeclaringType == entity)) 
      { 
       WriteNavigationTypeProperty(navProperty, code); 
      } 
     #> 
     } 
    } 

    <# 
     } 
     WriteLine(string.Empty); 
    #> 
} 
*/ 
<#+ 
    //////// 
    //////// Write PrimitiveType Properties. 
    //////// 
    private void WritePrimitiveTypeProperty(EdmProperty property, CodeGenerationTools code) 
    { 
     MetadataTools ef = new MetadataTools(this); 
     var dataTypeAtt = GetDataTypeAttribute(property, ef); 
     if (!property.Nullable) 
     { 
#> 
      [Required(ErrorMessage="<#=FixName(code.Escape(property))#> is required")] 
<#+ 
     } 
     foreach (Facet facet in property.TypeUsage.Facets) 
     { 
      if (facet.Name == "MaxLength" && facet.Value != null && facet.IsUnbounded == false) 
      { 
#> 
      [StringLength(<#=facet.Value#>)] 
<#+ 
      } 
     } 
     if (dataTypeAtt != String.Empty) 
     { 
#> 
      <#=dataTypeAtt#> 
<#+ 
     }  
#> 
      <#=code.SpaceAfter(NewModifier(property))#><#=Accessibility.ForProperty(property)#> <#=ef.ClrType(property.TypeUsage).Name#> <#=code.Escape(property)#> { get; set; } 

<#+ 
    } 

    //////// 
    //////// Write PrimitiveType Properties. 
    //////// 
    private void WriteNavigationTypeProperty(NavigationProperty navProperty, CodeGenerationTools code) 
    { 
#> 
      <#=code.SpaceAfter(NewModifier(navProperty))#><#=Accessibility.ForProperty(navProperty)#> EntityCollection<<#=MultiSchemaEscape(navProperty.ToEndMember.GetEntityType(), code)#>> <#=code.Escape(navProperty)#> { get; set; } 

<#+ 
    } 

public string FixName(string propName) 
{ 
    if (propName.ToLower() != "id" && propName.ToLower().EndsWith("id")) 
    { 
     propName = propName.Replace("Id","").Replace("ID",""); 
    } 
    return Regex.Replace(propName,"([A-Z])"," $1",RegexOptions.Compiled).Trim(); 
} 

public string GetDataTypeAttribute(EdmProperty property, MetadataTools ef) 
{ 
    var propLower = property.Name.ToLower(); 
    if (ef.ClrType(property.TypeUsage) == typeof(System.DateTime)) 
    { 
     return "[DataType(DataType.DateTime)]"; 
    } 
    if (propLower.Contains("phone")) 
    { 
     return "[DataType(DataType.PhoneNumber)]"; 
    } 
    if (propLower.Contains("html")) 
    { 
     return "[DataType(DataType.Html)]"; 
    } 
    if (propLower.Contains("email")) 
    { 
     return "[DataType(DataType.EmailAddress)]"; 
    } 
    if (propLower.Contains("url")) 
    { 
     return "[DataType(DataType.Url)]"; 
    } 
    return String.Empty; 
} 

//////// 
//////// Declare Template Public Properties. 
//////// 
public string SourceCsdlPath{ get; set; } 
public string ModelNamespace{ get; set; } 
public EdmItemCollection ItemCollection{ get; set; } 
public IEnumerable<string> ReferenceCsdlPaths{ get; set; } 
public Nullable<bool> CreateContextAddToMethods{ get; set; } 
public Dictionary<string, string> EdmToObjectNamespaceMap 
{ 
    get { return _edmToObjectNamespaceMap; } 
    set { _edmToObjectNamespaceMap = value; } 
} 
public Dictionary<string, string> _edmToObjectNamespaceMap = new Dictionary<string, string>(); 
public Double SourceEdmVersion 
{ 
    get 
    { 
     if (ItemCollection != null) 
     { 
      return ItemCollection.EdmVersion; 
     } 

     return 0.0; 
    } 
} 

//////// 
//////// Declare Template Private Properties. 
//////// 
static System.Resources.ResourceManager ResourceManager 
{ 
    get 
    { 
     if (_resourceManager == null) 
     { 
      System.Resources.ResourceManager resourceManager = new System.Resources.ResourceManager("System.Data.Entity.Design", typeof(System.Data.Entity.Design.MetadataItemCollectionFactory).Assembly); 
      System.Threading.Interlocked.CompareExchange(ref _resourceManager, resourceManager, null); 
     } 
     return _resourceManager; 
    } 
} 
static System.Resources.ResourceManager _resourceManager; 

#> 
<#+ 


private static string GetResourceString(string resourceName) 
{ 
    return ResourceManager.GetString(resourceName, 
     null); // Take default culture. 
} 



private void VerifyTypeUniqueness() 
{ 
    HashSet<string> hash = new HashSet<string>(); 
    IEnumerable<GlobalItem> allTypes = GetSourceSchemaTypes<GlobalItem>().Where(i => i is StructuralType || i is EntityContainer); 

    foreach (GlobalItem type in allTypes) 
    { 
     if (!hash.Add(GetGlobalItemName(type))) 
     { 
      // 6034 is the error number used by System.Data.Entity.Design EntityClassGenerator. 
      Errors.Add(new System.CodeDom.Compiler.CompilerError(SourceCsdlPath, -1, -1, "6034", 
      String.Format(CultureInfo.CurrentCulture, 
       GetResourceString("Template_DuplicateTopLevelType"), 
      GetGlobalItemName(type)))); 
     } 
    } 
} 

protected string GetGlobalItemName(GlobalItem item) 
{ 
    if (item is EdmType) 
    { 
     // EntityType or ComplexType. 
     return ((EdmType)item).Name; 
    } 
    else 
    { 
     // Must be an EntityContainer. 
     return ((EntityContainer)item).Name; 
    } 
} 



void ApplyUserSettings(UserSettings userSettings) 
{ 
    // Setup template UserSettings. 
    if (SourceCsdlPath == null) 
    { 
#if !PREPROCESSED_TEMPLATE 
     if(userSettings.SourceCsdlPath == "$" + "edmxInputFile" + "$") 
     { 
      Errors.Add(new System.CodeDom.Compiler.CompilerError(Host.TemplateFile, 0, 0, "", 
       GetResourceString("Template_ReplaceVsItemTemplateToken"))); 
      return; 
     } 

     SourceCsdlPath = Host.ResolvePath(userSettings.SourceCsdlPath); 
#else 
     SourceCsdlPath = userSettings.SourceCsdlPath; 
#endif 
    } 

    // normalize the path, remove ..\ from it 
    SourceCsdlPath = Path.GetFullPath(SourceCsdlPath); 


    if (ReferenceCsdlPaths == null) 
    { 
     ReferenceCsdlPaths = userSettings.ReferenceCsdlPaths; 
    } 

    if (!CreateContextAddToMethods.HasValue) 
    { 
     CreateContextAddToMethods = userSettings.CreateContextAddToMethods; 
    } 

    DefaultSummaryComment = GetResourceString("Template_CommentNoDocumentation"); 
} 


class UserSettings 
{ 
    public string SourceCsdlPath{ get; set; } 
    public string[] ReferenceCsdlPaths{ get; set; } 
    public bool FullyQualifySystemTypes{ get; set; } 
    public bool CreateContextAddToMethods{ get; set; } 
    public bool CamelCaseFields{ get; set; } 
} 

string MultiSchemaEscape(TypeUsage usage, CodeGenerationTools code) 
{ 
    StructuralType structural = usage.EdmType as StructuralType; 
    if (structural != null) 
    { 
     return MultiSchemaEscape(structural, code); 
    } 
    return code.Escape(usage); 
} 

string MultiSchemaEscape(StructuralType type, CodeGenerationTools code) 
{ 
    if (type.NamespaceName != ModelNamespace) 
    { 
     return code.CreateFullName(code.EscapeNamespace(GetObjectNamespace(type.NamespaceName)), code.Escape(type)); 
    } 

    return code.Escape(type); 
} 

string NewModifier(NavigationProperty navigationProperty) 
{ 
    Type baseType = typeof(EntityObject); 
    return NewModifier(baseType, navigationProperty.Name); 
} 

string NewModifier(EdmFunction edmFunction) 
{ 
    Type baseType = typeof(ObjectContext); 
    return NewModifier(baseType, edmFunction.Name); 
} 

string NewModifier(EntitySet set) 
{ 
    Type baseType = typeof(ObjectContext); 
    return NewModifier(baseType, set.Name); 
} 

string NewModifier(EdmProperty property) 
{ 
    Type baseType; 
    if (property.DeclaringType.BuiltInTypeKind == BuiltInTypeKind.EntityType) 
    { 
     baseType = typeof(EntityObject); 
    } 
    else 
    { 
     baseType = typeof(ComplexObject); 
    } 
    return NewModifier(baseType, property.Name); 
} 

string NewModifier(Type type, string memberName) 
{ 
    if (HasBaseMemberWithMatchingName(type, memberName)) 
    { 
     return "new"; 
    } 
    return string.Empty; 
} 

static bool HasBaseMemberWithMatchingName(Type type, string memberName) 
{ 
    BindingFlags bindingFlags = BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Public 
       | BindingFlags.Instance | BindingFlags.Static; 
    return type.GetMembers(bindingFlags).Where(m => IsVisibleMember(m)).Any(m => m.Name == memberName); 
} 

string ChangingMethodName(EdmMember member) 
{ 
    return string.Format(CultureInfo.InvariantCulture, "On{0}Changing", member.Name); 
} 

string ChangedMethodName(EdmMember member) 
{ 
    return string.Format(CultureInfo.InvariantCulture, "On{0}Changed", member.Name); 
} 

string InitializedTrackingField(EdmProperty property, CodeGenerationTools code) 
{ 
    string namePart = property.Name + "Initialized"; 
    if (code.CamelCaseFields) 
    { 
     namePart = code.CamelCase(namePart); 
    } 
    return "_" + namePart; 
} 

string OptionalNullableParameterForSetValidValue(EdmMember member, CodeGenerationTools code) 
{ 
    MetadataTools ef = new MetadataTools(this); 
    string list = string.Empty; 
    if (((PrimitiveType)member.TypeUsage.EdmType).ClrEquivalentType.IsClass) 
    { 
     MetadataProperty storeGeneratedPatternProperty = null; 
     bool isNullable = ef.IsNullable(member.TypeUsage) || 
      (member.MetadataProperties.TryGetValue(MetadataConstants.EDM_ANNOTATION_09_02 + ":StoreGeneratedPattern", false, out storeGeneratedPatternProperty) && 
      Object.Equals(storeGeneratedPatternProperty.Value, "Computed")); 
     list += ", " + code.CreateLiteral(isNullable); 
    } 
    return list; 
} 

static bool IsVisibleMember(MemberInfo memberInfo) 
{ 
    if (memberInfo is EventInfo) 
    { 
     EventInfo ei = (EventInfo)memberInfo; 
     MethodInfo add = ei.GetAddMethod(); 
     MethodInfo remove = ei.GetRemoveMethod(); 
     return IsVisibleMethod(add) || IsVisibleMethod(remove); 
    } 
    else if (memberInfo is FieldInfo) 
    { 
     FieldInfo fi = (FieldInfo)memberInfo; 
     return !fi.IsPrivate && !fi.IsAssembly; 
    } 
    else if (memberInfo is MethodBase) 
    { 
     MethodBase mb = (MethodBase)memberInfo; 
     if (mb.IsSpecialName) 
      return false; 
     return IsVisibleMethod(mb); 
    } 
    else if (memberInfo is PropertyInfo) 
    { 
     PropertyInfo pi = (PropertyInfo)memberInfo; 
     MethodInfo get = pi.GetGetMethod(); 
     MethodInfo set = pi.GetSetMethod(); 
     return IsVisibleMethod(get) || IsVisibleMethod(set); 
    } 

    return false; 
} 

static bool IsVisibleMethod(MethodBase methodBase) 
{ 
    if (methodBase == null) 
     return false; 

    return !methodBase.IsPrivate && !methodBase.IsAssembly; 
} 

IEnumerable<T> GetSourceSchemaTypes<T>() where T : GlobalItem 
{ 
    if (Path.GetExtension(SourceCsdlPath) != ".edmx") 
    { 
     return ItemCollection.GetItems<T>().Where(e => e.MetadataProperties.Any(mp => mp.Name == "SchemaSource" && (string)mp.Value == SourceCsdlPath)); 
    } 
    else 
    { 
     return ItemCollection.GetItems<T>(); 
    } 
} 

string EndName(AssociationType association, int index) 
{ 
    return association.AssociationEndMembers[index].Name; 
} 

string EndMultiplicity(AssociationType association, int index, CodeGenerationTools code) 
{ 
    return code.CreateLiteral(association.AssociationEndMembers[index].RelationshipMultiplicity); 
} 

string EscapeEndTypeName(AssociationType association, int index, CodeGenerationTools code) 
{ 
    EntityType entity = association.AssociationEndMembers[index].GetEntityType(); 
    return code.CreateFullName(code.EscapeNamespace(GetObjectNamespace(entity.NamespaceName)), code.Escape(entity)); 
} 

string GetObjectNamespace(string csdlNamespaceName) 
{ 
    string objectNamespace; 
    if (EdmToObjectNamespaceMap.TryGetValue(csdlNamespaceName, out objectNamespace)) 
    { 
     return objectNamespace; 
    } 

    return csdlNamespaceName; 
} 

void UpdateObjectNamespaceMap(string objectNamespace) 
{ 
    if(objectNamespace != ModelNamespace && !EdmToObjectNamespaceMap.ContainsKey(ModelNamespace)) 
    { 
     EdmToObjectNamespaceMap.Add(ModelNamespace, objectNamespace); 
    } 
} 

static string FixParameterName(string name, CodeGenerationTools code) 
{ 
    // Change any property that is 'id' (case insensitive) to 'ID' 
    // since 'iD' is a violation of FxCop rules. 
    if (StringComparer.OrdinalIgnoreCase.Equals(name, "id")) 
    { 
     // Return all lower case since it is an abbreviation, not an acronym. 
     return "id"; 
    } 
    return code.CamelCase(name); 
} 

string BaseTypeName(EntityType entity, CodeGenerationTools code) 
{ 
    return entity.BaseType == null ? "EntityObject" : MultiSchemaEscape((StructuralType)entity.BaseType, code); 
} 

bool IncludePropertyInFactoryMethod(StructuralType factoryType, EdmProperty edmProperty) 
{ 
    if (edmProperty.Nullable) 
    { 
     return false; 
    } 

    if (edmProperty.DefaultValue != null) 
    { 
     return false; 
    } 

    if ((Accessibility.ForReadOnlyProperty(edmProperty) != "public" && Accessibility.ForWriteOnlyProperty(edmProperty) != "public") || 
     (factoryType != edmProperty.DeclaringType && Accessibility.ForWriteOnlyProperty(edmProperty) == "private") 
     ) 
    { 
     // There is no public part to the property. 
     return false; 
    } 

    return true; 
} 


class FactoryMethodParameter 
{ 
    public EdmProperty Source; 
    public string RawParameterName; 
    public string ParameterName; 
    public string ParameterType; 
    public string ParameterComment; 
    public bool IsComplexType; 

    public static IEnumerable<FactoryMethodParameter> CreateParameters(IEnumerable<EdmProperty> properties, UniqueIdentifierService unique, Func<TypeUsage, CodeGenerationTools, string> multiSchemaEscape, CodeGenerationTools code) 
    { 
     List<FactoryMethodParameter> parameters = new List<FactoryMethodParameter>(); 
     foreach (EdmProperty property in properties) 
     { 
      FactoryMethodParameter parameter = new FactoryMethodParameter(); 
      parameter.Source = property; 
      parameter.IsComplexType = property.TypeUsage.EdmType is ComplexType; 
      parameter.RawParameterName = unique.AdjustIdentifier(FixParameterName(property.Name, code)); 
      parameter.ParameterName = code.Escape(parameter.RawParameterName); 
      parameter.ParameterType = multiSchemaEscape(property.TypeUsage, code); 
      parameter.ParameterComment = String.Format(CultureInfo.CurrentCulture, GetResourceString("Template_CommentFactoryMethodParam"), property.Name); 
      parameters.Add(parameter); 
     } 

     return parameters; 
    } 
} 

string DefaultSummaryComment{ get; set; } 

string SummaryComment(MetadataItem item) 
{ 
    if (item.Documentation != null && item.Documentation.Summary != null) 
    { 
     return PrefixLinesOfMultilineComment(XMLCOMMENT_START + " ", XmlEntityize(item.Documentation.Summary)); 
    } 

    if (DefaultSummaryComment != null) 
    { 
     return DefaultSummaryComment; 
    } 

    return string.Empty; 
} 

string LongDescriptionCommentElement(MetadataItem item, int indentLevel) 
{ 
    if (item.Documentation != null && !String.IsNullOrEmpty(item.Documentation.LongDescription)) 
    { 
     string comment = Environment.NewLine; 
     string lineStart = CodeRegion.GetIndent(indentLevel) + XMLCOMMENT_START + " "; 
     comment += lineStart + "<LongDescription>" + Environment.NewLine; 
     comment += lineStart + PrefixLinesOfMultilineComment(lineStart, XmlEntityize(item.Documentation.LongDescription)) + Environment.NewLine; 
     comment += lineStart + "</LongDescription>"; 
     return comment; 
    } 
    return string.Empty; 
} 

string PrefixLinesOfMultilineComment(string prefix, string comment) 
{ 
    return comment.Replace(Environment.NewLine, Environment.NewLine + prefix); 
} 

string ParameterComments(IEnumerable<Tuple<string, string>> parameters, int indentLevel) 
{ 
    System.Text.StringBuilder builder = new System.Text.StringBuilder(); 
    foreach (Tuple<string, string> parameter in parameters) 
    { 
     builder.AppendLine(); 
     builder.Append(CodeRegion.GetIndent(indentLevel)); 
     builder.Append(XMLCOMMENT_START); 
     builder.Append(String.Format(CultureInfo.InvariantCulture, " <param name=\"{0}\">{1}</param>", parameter.Item1, parameter.Item2)); 
    } 
    return builder.ToString(); 
} 

string XmlEntityize(string text) 
{ 
    if (string.IsNullOrEmpty(text)) 
    { 
     return string.Empty; 
    } 

    text = text.Replace("&","&amp;"); 
    text = text.Replace("<","&lt;").Replace(">","&gt;"); 
    string id = Guid.NewGuid().ToString(); 
    text = text.Replace(Environment.NewLine, id); 
    text = text.Replace("\r", "&#xD;").Replace("\n","&#xA;"); 
    text = text.Replace(id, Environment.NewLine); 
    return text.Replace("\'","&apos;").Replace("\"","&quot;"); 
} 

const string XMLCOMMENT_START = "///"; 
IEnumerable<EdmProperty> GetProperties(StructuralType type) 
{ 
    if (type.BuiltInTypeKind == BuiltInTypeKind.EntityType) 
    { 
     return ((EntityType)type).Properties; 
    } 
    else 
    { 
     return ((ComplexType)type).Properties; 
    } 
} 

protected void VerifyGetterAndSetterAccessibilityCompatability(EdmMember member) 
{ 
    string rawGetterAccessibility = Accessibility.ForReadOnlyProperty(member); 
    string rawSetterAccessibility = Accessibility.ForWriteOnlyProperty(member); 

    if ((rawGetterAccessibility == "internal" && rawSetterAccessibility == "protected") || 
     (rawGetterAccessibility == "protected" && rawSetterAccessibility == "internal")) 

    { 
      Errors.Add(new System.CodeDom.Compiler.CompilerError(SourceCsdlPath, -1, -1, "6033", String.Format(CultureInfo.CurrentCulture, 
        GetResourceString("GeneratedPropertyAccessibilityConflict"), 
         member.Name, rawGetterAccessibility, rawSetterAccessibility))); 
    } 
} 

private void VerifyEntityTypeAndSetAccessibilityCompatability(EntitySet set) 
{ 
    string typeAccess = Accessibility.ForType(set.ElementType); 
    string setAccess = Accessibility.ForReadOnlyProperty(set); 

    if(typeAccess == "internal" && (setAccess == "public" || setAccess == "protected")) 
    { 
     Errors.Add(new System.CodeDom.Compiler.CompilerError(SourceCsdlPath, -1, -1, "6036", String.Format(CultureInfo.CurrentCulture, 
       GetResourceString("EntityTypeAndSetAccessibilityConflict"), 
        set.ElementType.Name, typeAccess, set.Name, setAccess))); 
    } 
} 

//////// 
//////// UniqueIdentifierService 
//////// 
sealed class UniqueIdentifierService 
{ 
    private readonly HashSet<string> _knownIdentifiers; 

    public UniqueIdentifierService() 
    { 
     _knownIdentifiers = new HashSet<string>(StringComparer.Ordinal); 
    } 

    /// <summary> 
    /// Makes the supplied identifier unique within the scope by adding 
    /// a suffix (1, 2, 3, ...), and returns the unique identifier. 
    /// </summary> 
    public string AdjustIdentifier(string identifier) 
    { 
     // find a unique name by adding suffix as necessary 
     var numberOfConflicts = 0; 
     var adjustedIdentifier = identifier; 

     while (!_knownIdentifiers.Add(adjustedIdentifier)) 
     { 
      ++numberOfConflicts; 
      adjustedIdentifier = identifier + numberOfConflicts.ToString(CultureInfo.InvariantCulture); 
     } 

     return adjustedIdentifier; 
    } 
} 

#> 

이 아주 약간 나는 생성 된 코드는 그래서 실제로 프로젝트에 컴파일되지 않습니다 주석 한 점에서 댄의 원본과 수정 : 여기 내가 사용하는 템플릿입니다. 메타 데이터 클래스 스타터 준비가되면 생성 된 단일 파일에서 적절한 코드를 복사하여 메타 데이터 정의에 사용할 실제 코드 파일에 붙여 넣기 만하면됩니다. 데이터 주석을 추가하여 각 템플릿 빌드에서 덮어 쓰지 않도록 할 수 있습니다.

관련 문제