EF7 (코어)에서 사용자 정의 속성 사용 OnModelCreating

c# ef-code-first entity-framework entity-framework-core npgsql

문제

나는 이렇게 정의 된 DefaultAttribute 있다 :

[AttributeUsage(AttributeTargets.Property)]
public class DefaultAttribute : Attribute
{
    /// <summary>
    /// Specifies this property has a default value upon creation.
    /// </summary>
    /// <param name="defaultValue">The default value of the property.</param>
    /// <param name="useAsLiteral">Set to true if the value is <em>not</em> quoted in the DDL.</param>
    public DefaultAttribute(object defaultValue, bool useAsLiteral = false)
    {
        DefaultValue = defaultValue;
        UseAsLiteral = useAsLiteral;
    }

    public object DefaultValue { get; private set; }

    /// <summary>
    /// True if the default value is not quoted in the DDL
    /// </summary>
    public bool UseAsLiteral { get; private set; }
}

다음과 같이이 속성을 가진 엔티티 중 몇 개를 장식했습니다.

public class MyEntity
{
    . . . (other properties) . . .
    [StringLength(200)]
    [Required]
    [Default("My Default Description!")]
    public string Description { get; set; }
}

그런 다음 내 데이터베이스 컨텍스트의 OnModelCreating 메서드에서 다음 코드를 작성했습니다.

//examine custom annotations for shaping the schema in the database.
foreach (var entityType in builder.Model.GetEntityTypes())
    foreach (var property in entityType.GetProperties())
    {
        var annotations = property.GetAnnotations();

        // evaluate default values
        var defaultAnnotation = annotations.FirstOrDefault(x => x.Name == typeof(DefaultAttribute).FullName);
        if (defaultAnnotation != null)
        {
            var defaultValue = defaultAnnotation.Value as DefaultAttribute;
            if (defaultValue == null) continue;

            if (defaultValue.UseAsLiteral)
                property.Npgsql().DefaultValueSql = defaultValue.DefaultValue.ToString();
            else
                property.Npgsql().DefaultValue = defaultValue.DefaultValue;
        }
    }

마이 그 레이션을 추가 할 때 (그리고 후속 데이터베이스 업데이트) 내 기대치는 "내 기본 설명!"이라는 기본값이 있다는 것입니다. 그러나 MyEntityDescription 열에 MyEntity ..., 그렇지 않습니다.

오류가 발생하지는 않지만 의심 OnModelCreating 하지 않으며 중단 점을 사용하여 OnModelCreating 을 수행하는 것도 이해하기 어려운 일입니다.

이 일을 제대로하고 있습니까? 그것은 단지 작동하지 않습니까? EF7에서는 지원되지 않습니까? 또는 PostgreSQL 구현에서 지원되지 않습니까? 모든 통찰력은 인정 될 것이다.

업데이트 @ IvanStoev의 대답을 사용하여 약간의 수정 (.NET Core의 Reflection은 전통적인 것과 약간 다름)으로이 작업을 수행 할 수있었습니다.

//examine custom annotations for shaping the schema in the database.
foreach (var entityType in builder.Model.GetEntityTypes())
    foreach (var property in entityType.GetProperties())
    {
        var memberInfo = property.PropertyInfo ?? (MemberInfo)property.FieldInfo;
        var defaultValue = memberInfo?.GetCustomAttribute<DefaultAttribute>();
        if (defaultValue == null) continue;
        if (defaultValue.UseAsLiteral)
            property.Npgsql().DefaultValueSql = defaultValue.DefaultValue.ToString();
        else
            property.Npgsql().DefaultValue = defaultValue.DefaultValue;
    }

이것은 챔피언처럼 일했습니다.

수락 된 답변

EF Core는 사용자 정의 속성에 대해 아무 것도 모릅니다. 따라서 주석을 검색하고 노출 할 방법이 없습니다 (일반적으로 속성과 반드시 ​​관련이없는 다른 속성).

속성이있는 경우 PropertyInfo 또는 FieldInfo 에서 속성을 수동으로 추출해야합니다.

foreach (var entityType in builder.Model.GetEntityTypes())
    foreach (var property in entityType.GetProperties())
    {
        var memberInfo = property.PropertyInfo ?? (MemberInfo)property.FieldInfo;
        if (memberInfo == null) continue;
        var defaultValue = Attribute.GetCustomAttribute(memberInfo, typeof(DefaultAttribute)) as DefaultAttribute;
        if (defaultValue == null) continue;
        if (defaultValue.UseAsLiteral)
            property.Npgsql().DefaultValueSql = defaultValue.DefaultValue.ToString();
        else
            property.Npgsql().DefaultValue = defaultValue.DefaultValue;
    }


Related

아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.