[c#] 엔티티 프레임 워크에서 생성 된 클래스에 데이터 주석 추가
엔터티 프레임 워크에서 생성 한 다음 클래스가 있습니다.
public partial class ItemRequest
{
public int RequestId { get; set; }
//...
이 필드를 필수 필드로 만들고 싶습니다.
[Required]
public int RequestId { get;set; }
그러나 이것은 생성 된 코드이기 때문에 지워질 것입니다. 속성이 생성 된 부분 클래스에 의해 정의되기 때문에 부분 클래스를 만드는 방법을 상상할 수 없습니다. 안전한 방식으로 제약 조건을 어떻게 정의 할 수 있습니까?
답변
생성 된 클래스 ItemRequest
는 항상 partial
클래스입니다. 이를 통해 필요한 데이터 주석으로 표시된 두 번째 부분 클래스를 작성할 수 있습니다. 귀하의 경우 부분 클래스 ItemRequest
는 다음과 같습니다.
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
//make sure the namespace is equal to the other partial class ItemRequest
namespace MvcApplication1.Models
{
[MetadataType(typeof(ItemRequestMetaData))]
public partial class ItemRequest
{
}
public class ItemRequestMetaData
{
[Required]
public int RequestId {get;set;}
//...
}
}
답변
MUG4N이 대답 했듯이 부분 클래스를 사용할 수 있지만 대신 인터페이스 를 사용하는 것이 좋습니다 . 이 경우 EF 모델이 유효성 검사 모델과 일치하지 않으면 컴파일 오류가 발생합니다. 따라서 유효성 검사 규칙이 오래되었다는 두려움없이 EF 모델을 수정할 수 있습니다.
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace YourApplication.Models
{
public interface IEntityMetadata
{
[Required]
Int32 Id { get; set; }
}
[MetadataType(typeof(IEntityMetadata))]
public partial class Entity : IEntityMetadata
{
/* Id property has already existed in the mapped class */
}
}
PS ASP.NET MVC와 다른 프로젝트 유형을 사용하는 경우 (수동 데이터 유효성 검사를 수행 할 때) 유효성 검사기를 등록하는 것을 잊지 마십시오.
/* Global.asax or similar */
TypeDescriptor.AddProviderTransparent(
new AssociatedMetadataTypeTypeDescriptionProvider(typeof(Entity), typeof(IEntityMetadata)), typeof(Entity));
답변
MUG4N 의 답변 과 같은 솔루션을 찾았 지만 대신 MetaData
엔티티 클래스 내에 클래스를 중첩 하여 공용 네임 스페이스 목록의 클래스 수를 줄이고 각 메타 데이터 클래스에 대해 고유 한 이름을 가질 필요가 없습니다.
using System.ComponentModel.DataAnnotations;
namespace MvcApplication1.Models
{
[MetadataType(typeof(MetaData))]
public partial class ItemRequest
{
public class MetaData
{
[Required]
public int RequestId;
//...
}
}
}
답변
이것은 db 모델을 재생성하는 경우 @dimonser 답변에 대한 일종의 확장이며 해당 클래스에 인터페이스를 수동으로 다시 추가해야합니다.
위가 있다면 .tt
템플릿을 수정할 수도 있습니다 .
다음은 일부 클래스에서 인터페이스를 자동으로 생성하는 예입니다. 이것은 다음과 같이 (그리고 분명히 엔티티 이름과 인터페이스로) 사용자의 메소드를 .tt
대체 EntityClassOpening
하는 것입니다 var stringsToMatch
.
public string EntityClassOpening(EntityType entity)
{
var stringsToMatch = new Dictionary<string,string> { { "Answer", "IJourneyAnswer" }, { "Fee", "ILegalFee" } };
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1}partial class {2}{3}{4}",
Accessibility.ForType(entity),
_code.SpaceAfter(_code.AbstractOption(entity)),
_code.Escape(entity),
_code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)),
stringsToMatch.Any(o => _code.Escape(entity).Contains(o.Key)) ? " : " + stringsToMatch.Single(o => _code.Escape(entity).Contains(o.Key)).Value : string.Empty);
}
정상적인 사람은 스스로 이것을해서는 안되며,이를 위해 지옥에 간다는 것이 성경에서 입증되었습니다.
답변
나는 당신이 요구하는 것을 어떻게하는지 잘 모르겠지만 그에 대한 방법이 있습니다. 사용자 지정 DataAnnotationsModelValidatorProvider의 GetValidators를 재정 의하여 동적 데이터 유효성 검사. 여기에서 (데이터베이스, 구성 파일 등에서) 각 필드의 유효성을 검사하는 규칙을 읽고 필요에 따라 유효성 검사기를 추가 할 수 있습니다. 유효성 검사가 더 이상 모델과 밀접하게 결합되지 않고 사이트를 다시 시작하지 않고도 변경할 수 있다는 부가 가치가 있습니다. 물론 귀하의 경우에는 과잉 일 수 있지만 우리에게는 이상적이었습니다!
답변
필요한 주석을 추가하여 T4 템플릿을 수정합니다.이 파일의 이름은 일반적으로 MODELNAME.tt입니다.
T4가 클래스와 메서드를 생성하는 위치를 찾아이를 어디에 둘지 알 수 있습니다.
<#=codeStringGenerator.IgnoreJson(navigationProperty)#>
//create this method in file
public string IgnoreJson(NavigationProperty navigationProperty){
string result = navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? "" : @"[JsonIgnore]
[IgnoreDataMember]";
return result;
}
네임 스페이스도 추가해야합니다.
<#=codeStringGenerator.UsingDirectives(inHeader: false)#>
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
using System.Runtime.Serialization;
모델을 저장하여 클래스를 다시 빌드하십시오. 모든 메소드에 주석을 달아야합니다.