3
我有一個DefaultAttribute
定義,像這樣:使用EF7(核心)OnModelCreating自定義屬性
[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;
}
}
我的期望是,在添加遷移時(和隨後的數據庫更新),會有一個默認值「我的默認描述!」對於Description
列MyEntity
...但是,情況並非如此。
我沒有得到任何錯誤,但它沒有按照我的想法去做,並且用斷點進入OnModelCreating
也是難以理解的。
我是否正確地做到了這一點?它不工作嗎?它只是在EF7不支持?或者在我的PostgreSQL實現中不支持?任何洞察力將不勝感激。
UPDATE 使用@ IvanStoev的回答,我能得到這個有一些小的modifiactions工作(反映在.NET核心從傳統的有點不同):
//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;
}
這工作就像一個冠軍。
注意,有沒有真正的理由這樣做'.Npgsql()' - 這對只爲Npgsql的設置默認值,當針對多個數據庫。在大多數情況下,您應該簡單地執行'property.HasDefaultValue(...)'(請參閱https://docs.microsoft.com/en-us/ef/core/modeling/relational/default-values) –