엔티티 프레임 워크 코드에 사용자 정의 속성 속성 추가
-
20-08-2019 - |
문제
EF 생성 코드의 속성에 사용자 정의 속성을 추가 할 수있는 방법이 있습니까? 내가 그럴듯한 솔루션으로 볼 수있는 유일한 것은 맞춤형 T4 템플릿을 만들어내는 것입니다. 그러나 속성의 특성으로 인해 EF 속성 당 올바른 속성 매개 변수를 결정하는 것은 불가능합니다.
해결책
속성을 반영하고 단순히 속성에 사용되는 메타 데이터 유형을 지정하여이를 수행 할 수 있습니다.
[MetadataType(typeof(Dinner_Validation))]
public partial class Dinner
{}
public class Dinner_Validation
{
[Required]
public string Title { get; set; }
}
스티브 스미스 블로그에 대해 블로그 여기.
불행히도 위의 접근 방식은 재 획득에 부서지기 쉽습니다. 또 다른 옵션은 새로운 Poco 엔티티를 사용하는 것입니다. 이것들은 내가 알 수있는 한 컴파일 타임 코드 생성을 모두 피합니다. 나는 아직 그것들을 사용하지 않았으므로 함정이나 트레이드 오프에 대해서는 언급 할 수 없습니다.
다른 팁
디자이너와 함께 EDMX 파일에 추가 할 수 있습니다.
<Property Name="Nome" Type="String" Nullable="false" MaxLength="50" Unicode="true" FixedLength="false" >
<Documentation>
<Summary>[MyCustomAttribute]</Summary>
</Documentation>
</Property>
T4 교체 :
void WriteProperty(CodeGenerationTools code, EdmProperty edmProperty)
{
WriteProperty(Accessibility.ForProperty(edmProperty),
code.Escape(edmProperty.TypeUsage),
code.Escape(edmProperty),
code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
}
와 함께:
void WriteProperty(CodeGenerationTools code, EdmProperty edmProperty)
{
if(edmProperty.Documentation != null && string.IsNullOrWhiteSpace(edmProperty.Documentation.Summary) == false)
{
#>
<#=edmProperty.Documentation.Summary#>
<#+
}
WriteProperty(Accessibility.ForProperty(edmProperty),
code.Escape(edmProperty.TypeUsage),
code.Escape(edmProperty),
code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
}
인터페이스를 작성하고 인터페이스에서 속성을 선언 할 수 있습니다.
partial class Person : IPerson {}
public interface IPerson
{
[Required]
string Name { get; set; }
}
디자이너와 함께 EDMX 파일에 추가 할 수 있습니다.
<Property Name="Nome" Type="String" Nullable="false" MaxLength="50" Unicode="true" FixedLength="false" >
<Documentation>
<Summary>[MyCustomAttribute]</Summary>
</Documentation>
</Property>
T4 교체 :
void WriteProperty(CodeGenerationTools code, EdmProperty edmProperty)
{
WriteProperty(Accessibility.ForProperty(edmProperty),
code.Escape(edmProperty.TypeUsage),
code.Escape(edmProperty),
code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
}
와 함께:
void WriteProperty(CodeGenerationTools code, EdmProperty edmProperty)
{
if(edmProperty.Documentation != null && string.IsNullOrWhiteSpace(edmProperty.Documentation.Summary) == false)
{
#>
<#=edmProperty.Documentation.Summary#>
<#+
}
WriteProperty(Accessibility.ForProperty(edmProperty),
code.Escape(edmProperty.TypeUsage),
code.Escape(edmProperty),
code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
}
엔티티 프레임 워크 6의 경우 교체하십시오
public string Property(EdmProperty edmProperty)
{
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1} {2} {{ {3}get; {4}set; }}",
Accessibility.ForProperty(edmProperty),
_typeMapper.GetTypeName(edmProperty.TypeUsage),
_code.Escape(edmProperty),
_code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
_code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
}
~와 함께
public string Property(EdmProperty edmProperty)
{
var description = String.Empty;
bool isAttribute = false;
if(edmProperty.Documentation != null &&
string.IsNullOrWhiteSpace(edmProperty.Documentation.Summary) == false)
{
string summary = edmProperty.Documentation.Summary;
if (!String.IsNullOrEmpty(summary) && summary.First() == '[' && summary.Last() == ']')
{
isAttribute = true;
}
if (isAttribute)
{
description = String.Format("\r\n\t{0}\r\n\t", summary);
}
else
{
description = String.Format("\r\n\t/// <summary>\r\n\t/// {0}\r\n\t/// </summary>\r\n\t",
summary);
}
}
return string.Format(
CultureInfo.InvariantCulture,
"{5}{0} {1} {2} {{ {3}get; {4}set; }}",
Accessibility.ForProperty(edmProperty),
_typeMapper.GetTypeName(edmProperty.TypeUsage),
_code.Escape(edmProperty),
_code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
_code.SpaceAfter(Accessibility.ForSetter(edmProperty)),
description);
}
경고 :
- 네임 스페이스는 절대적으로 해결해야합니다.
- 속성이 '[' '로 시작하고 끝나는 것으로 가정합니다.
- 오프닝 및 닫는 브레이스를 찾을 수없는 경우 엔티티 프레임 워크 속성 요약이 XML 트리플 슬래시 주석으로 래핑됩니다.
- 프로젝트의 경우에도 그렇지 않을 수도있는 기본 Visual Studio Styling Information과 일치하려고 시도합니다. 여기에는 새로운 라인이 포함됩니다.
샘플 출력 :
/// <summary>
/// content type
/// </summary>
public System.Guid ContentType { get; set; }
[System.ComponentModel.DisplayName("Last Modified")]
public System.DateTime LastModified { get; set; }
나는 당신이 할 수 있다고 믿지 않습니다. 발전기는 모든 클래스를 부분적으로 선언하여 확장 할 수 있지만, 단순히 그 위에 생성 할 때 사용자 정의 속성으로 속성을 표시 할 수는 없습니다. 당신이 할 수있는 한 가지는 자신의 엔티티를 작성하는 것입니다.
Burnsba의 답변 외에도 내비게이션 속성에도 적용하려면 업데이트하십시오. NavigationProperty()
또한:
public string NavigationProperty(NavigationProperty navProp)
{
var description = String.Empty;
if(navProp.Documentation != null && string.IsNullOrWhiteSpace(navProp.Documentation.Summary) == false)
{
string summary = navProp.Documentation.Summary;
if (!String.IsNullOrEmpty(summary) && summary.First() == '[' && summary.Last() == ']')
{
description = String.Format("\r\n\t{0}\r\n\t", summary);
}
else
{
description = String.Format("\r\n\t/// <summary>\r\n\t/// {0}\r\n\t/// </summary>\r\n\t", summary);
}
}
var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType());
return string.Format(
CultureInfo.InvariantCulture,
"{5}{0} {1} {2} {{ {3}get; {4}set; }}",
AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)),
navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
_code.Escape(navProp),
_code.SpaceAfter(Accessibility.ForGetter(navProp)),
_code.SpaceAfter(Accessibility.ForSetter(navProp)),
description);
}
나는 이것을 추가하여 추가합니다 [Newtonsoft.Json.JsonIgnore]
내 속성에.
참고 : 이것을 추가해야합니다 <...>Model.tt
그리고 아닙니다 <...>Model.Context.tt