using System; using System.Data; using System.Reflection; using ZeroLevel.Services.ObjectMapping; using ZeroLevel.Services.Reflection; namespace ZeroLevel.MsSql { public class DbField : MapMemberInfo, IDbField { public bool AutoIncrement { get; internal set; } public bool IsIdentity { get; internal set; } public bool IsIndexed { get; internal set; } public bool AllowNull { get; internal set; } public long Size { get; internal set; } public DbType DbType { get; internal set; } private DbField(Action setter, Func getter) :base(setter, getter) { } private static bool IsNullable(Type type) { if (!type.IsValueType) return true; // ref-type if (Nullable.GetUnderlyingType(type) != null) return true; // Nullable return false; // value-type } public static DbField FromField(FieldInfo fieldInfo) { var meta = ((DbMemberAttribute)Attribute.GetCustomAttribute(fieldInfo, typeof(DbMemberAttribute))); var index = ((DbIndexAttribute)Attribute.GetCustomAttribute(fieldInfo, typeof(DbIndexAttribute))); var field = new DbField(TypeGetterSetterBuilder.BuildSetter(fieldInfo), TypeGetterSetterBuilder.BuildGetter(fieldInfo)) { Name = fieldInfo.Name, IsIdentity = meta?.IsIdentity ?? false, AllowNull = meta?.AllowNull ?? true, AutoIncrement = meta?.AutoIncrement ?? false, Size = meta?.Size ?? -1, IsIndexed = index != null }; field.IsField = true; var type = fieldInfo.FieldType; field.ClrType = type; field.DbType = type.ToDbType(); return field; } public static DbField FromProperty(PropertyInfo propertyInfo) { var meta = ((DbMemberAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(DbMemberAttribute))); var index = ((DbIndexAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(DbIndexAttribute))); var field = new DbField(TypeGetterSetterBuilder.BuildSetter(propertyInfo), TypeGetterSetterBuilder.BuildGetter(propertyInfo)) { Name = propertyInfo.Name, IsIdentity = meta?.IsIdentity ?? false, AllowNull = meta?.AllowNull ?? true, AutoIncrement = meta?.AutoIncrement ?? false, Size = meta?.Size ?? -1, IsIndexed = index != null }; field.IsField = false; var type = propertyInfo.PropertyType; field.ClrType = type; field.DbType = type.ToDbType(); return field; } public new static DbField FromMember(MemberInfo memberInfo) { switch (memberInfo.MemberType) { case MemberTypes.Field: return FromField(memberInfo as FieldInfo); case MemberTypes.Property: return FromProperty(memberInfo as PropertyInfo); } return null; } public void SetValue(object instance, object dbvalue, Func converter = null) { var value = (null == dbvalue || DBNull.Value == dbvalue) ? null : dbvalue; if (null != converter) { value = converter(this, value); } if (null == value && false == IsNullable(ClrType)) Setter(instance, TypeExtensions.GetDefault(ClrType)); else Setter(instance, value); } } }