[英]Using a custom attribute in EF7 (core) OnModelCreating
我有一個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;
}
}
在添加遷移(以及后續數據庫更新)時,我的期望是默認值為“我的默認描述!”。 對於MyEntity
的Description
列...但是,情況並非如此。
我沒有得到任何錯誤,但它沒有像我懷疑的那樣做,並且使用斷點進入OnModelCreating
也難以理解。
我這樣做了嗎? 它不起作用嗎? 它只是不支持EF7嗎? 或者我的PostgreSQL實現不支持它? 任何見解將不勝感激。
更新使用@ IvanStoev的答案,我能夠使用一些小的修改(.NET Core中的反射與傳統的有點不同):
//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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.