[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;

모델을 저장하여 클래스를 다시 빌드하십시오. 모든 메소드에 주석을 달아야합니다.


답변