嘗試對已有設定DecimalAttribute的Model在OnModelCreating的時候,把所有的都一次設定完
首先建立一個靜態類別DecimalModelCreating,並建立設定方法OnModelCreating(如下)
public static class DecimalModelCreating { public static void OnModelCreating(DbModelBuilder modelBuilder, string Namespace) { //取得所有在指定命名空間中,有欄位包含DecimalAttribute的類別 foreach (Type classType in from t in Assembly.GetAssembly(typeof(DecimalAttribute)).GetTypes() where t.IsClass == true && string.IsNullOrEmpty(t.Namespace) == false && t.Namespace.Equals(Namespace, StringComparison.CurrentCultureIgnoreCase) == true && t.GetProperties(BindingFlags.Public | BindingFlags.Instance).Any(p => p.GetCustomAttribute<DecimalAttribute>() != null) select t) { //取得類別中,包含DecimalAttribute的欄位 foreach (var propAttr in classType.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.GetCustomAttribute<DecimalAttribute>() != null).Select(p => new { prop = p, attr = p.GetCustomAttribute<DecimalAttribute>(true) })) { var entityConfig = modelBuilder.GetType().GetMethod("Entity").MakeGenericMethod(classType).Invoke(modelBuilder, null); ParameterExpression param = ParameterExpression.Parameter(classType, "c"); Expression property = Expression.Property(param, propAttr.prop.Name); LambdaExpression lambdaExpression = Expression.Lambda(property, true, new ParameterExpression[] { param }); DecimalPropertyConfiguration decimalConfig; MethodInfo methodInfo; //依欄位是否允許null,設定對應MethodInfo if (propAttr.prop.PropertyType.IsGenericType && propAttr.prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) { methodInfo = entityConfig.GetType().GetMethods().Where(p => p.Name == "Property").ToList()[7]; } else { methodInfo = entityConfig.GetType().GetMethods().Where(p => p.Name == "Property").ToList()[6]; } decimalConfig = methodInfo.Invoke(entityConfig, new[] { lambdaExpression }) as DecimalPropertyConfiguration; decimalConfig.HasPrecision((byte)propAttr.attr.Precision, (byte)propAttr.attr.Scale); } } } }
接著將DbContext的OnModelCreating調整為使用DecimalModelCreating進行設定
protected override void OnModelCreating(DbModelBuilder modelBuilder) { DecimalModelCreating.OnModelCreating(modelBuilder, "YourNamespance"); base.OnModelCreating(modelBuilder); }
參考:
Entity Framework Code First建立Decimal,並設定大小
2015/01/19調整:
近期將部分資料表移到Azure Storage Table的時候,發生了資料庫移轉錯誤
在模型產生期間偵測到一個或多個驗證錯誤: System.Data.Entity.Edm.EdmEntityType: : EntityType 'myclass' 未定義索引鍵。請定義此 EntityType 的索引鍵。 System.Data.Entity.Edm.EdmEntitySet: EntityType: EntitySet 'myclass' 是以未定義索引鍵的類型 'myclass' 為基礎。
檢查OnModelCreating後發現,在條件中,只要是在指定命名空間(Namespace)的Model都會被設定:
t.Namespace.Equals(Namespace, StringComparison.CurrentCultureIgnoreCase) == true
增加判斷語法,除了命名空間以外,還要有宣告在DbContext裡面:
typeof(MyContext).GetProperties().Where(x => x.PropertyType.IsGenericType && x.PropertyType.Name.StartsWith("DbSet") && x.PropertyType.GenericTypeArguments != null && x.PropertyType.GenericTypeArguments.Count() > 0).SelectMany(x => x.PropertyType.GenericTypeArguments).Select(x => x.Name).Contains(t.Name)
參考:
Entity Framework Code First建立Decimal,並設定大小
延伸閱讀:
Entity Framework Code First依屬性(Attribute)設定SQL欄位 (續)
沒有留言 :
張貼留言