public void CompileTest() { var classToGenerate = "GeneratedUser"; string generateClass = generator.GenerateClass("Users", classToGenerate); Assembly assembly = DbCompilerUtils.Compile(generateClass); Type type = assembly.GetType(generator.Namespace + "." + classToGenerate); ulong count = DbGateway.Instance.LoadCount(type); Assert.AreEqual(1, count); DbRecordInfo info1 = DbAttributesManager.GetRecordInfo(typeof(User)); DbRecordInfo info2 = DbAttributesManager.GetRecordInfo(type); Assert.AreEqual(info1.TableName, info2.TableName, "TableName"); DbFieldInfo pk = (info1 as DbIdentityRecordInfo).PrimaryKey; Assert.AreEqual(pk.FieldType, info2.Fields[0].FieldType); Assert.AreEqual(pk.Name, info2.Fields[0].Name); Assert.AreEqual(typeof(short), info2.Fields[1].FieldType); for (int i = 1; i < info2.Fields.Length - 1; i++) { Assert.AreEqual(info1.Fields[i], info2.Fields[i + 1], "Fields"); } }
internal override void CreateTable(DbRecordInfo info) { StringBuilder sb = new StringBuilder("CREATE TABLE " + info.TableName + "("); DbIdentityRecordInfo identityRecordInfo = info as DbIdentityRecordInfo; if (identityRecordInfo != null) { DbFieldInfo key = identityRecordInfo.PrimaryKey; if (key.FieldType == typeof(Guid)) { sb.Append(GetDefinition(key) + " NOT NULL"); } else { sb.Append(GetDefinition(key) + " NOT NULL IDENTITY(1,1)"); } sb.Append(','); } foreach (DbFieldInfo field in info.Fields) { sb.Append(GetDefinition(field)); sb.Append(','); } string[] keys = getPrimaryKeys(info); sb.AppendFormat("PRIMARY KEY ({0})", String.Join(",", keys)); DbIndexesInfo indexes = DbAttributesManager.GetIndexes(info.Fields); ProcessIndexes(sb, indexes.Unique, ",UNIQUE ({0})"); //TODO: (MSSQL) CREATE FULLTEXT INDEX //TODO: (MSSQL) CREATE INDEX // ProcessIndexes(sb, indexes.Indexes, ",KEY {1} ({0})"); // ProcessIndexes(sb, indexes.FullText, ",FULLTEXT KEY {1} ({0})"); //process foreign keys foreach (KeyValuePair <Type, DbFieldInfo> key in info.ForeignKeys) { DbIdentityRecordInfo ri = DbAttributesManager.GetRecordInfo(key.Key) as DbIdentityRecordInfo; if (ri == null) { throw new NdbException("Only DbIdentityRecord objects can be used as Foreign Keys"); } sb.AppendFormat( ",FOREIGN KEY ([{1}]) REFERENCES [{0}] ([{2}]) ON DELETE CASCADE ON UPDATE CASCADE" , ri.TableName , key.Value.Name , ri.PrimaryKey.Name); } sb.Append(")"); string query = sb.ToString(); ExecuteNonQuery(query); }
private void insert(DbIdentityRecordInfo info, object data) { DbFieldInfo primaryKey = info.PrimaryKey; if (primaryKey.FieldType == typeof(Guid)) { Guid guid = Guid.NewGuid(); primaryKey.SetValue(data, guid); object[] values = info.GetValues(data, primaryKey.Name, guid); Accessor.Insert(info.TableName, values); } else if (!info.IsDbGeneratedPrimaryKey) { object[] values = info.GetValues(data, primaryKey.Name, primaryKey.GetValue(data)); Accessor.Insert(info.TableName, values); } else { object[] values = info.GetValues(data); object newId = Accessor.InsertIdentity(info.TableName, primaryKey.Name, values); primaryKey.SetValue(data, Convert.ChangeType(newId, primaryKey.FieldType)); } }
public static object GetValue(DbFieldInfo field, object value) { Type type = GetType(field.FieldType); return(field.IsDiffersFromDatabaseType ? convertData(type, value) : fixData(type, value)); }
/// <summary> /// Gets SQL definition for a specifyed field /// </summary> /// <param name="field"></param> /// <returns>SDL column definition</returns> internal string GetDefinition(DbFieldInfo field) { StringBuilder sb = new StringBuilder(field.Name); sb.Append(' '); sb.Append(GetSqlType(field)); return(sb.ToString()); }
private void GetFields(TableInfo table) { string _sqltext = $@"SELECT ORDINAL_POSITION ,COLUMN_NAME ,IS_NULLABLE ,COLUMN_TYPE ,(CASE WHEN COLUMN_TYPE IN ('tinyint(1)','char(36)') THEN COLUMN_TYPE ELSE DATA_TYPE END) AS DATA_TYPE ,COLUMN_COMMENT ,COALESCE( CASE WHEN DATA_TYPE IN ('tinyint','smallint','mediumint','int','bigint','bit','double','float','decimal') THEN NUMERIC_PRECISION WHEN DATA_TYPE IN ('date','time','year','timestamp','datetime') THEN DATETIME_PRECISION ELSE CHARACTER_MAXIMUM_LENGTH END ,0) AS LENGTEH ,COALESCE(NUMERIC_SCALE,0) AS NUMERIC_SCALE ,(EXTRA='auto_increment') as auto_increment from information_schema.`COLUMNS` where TABLE_SCHEMA='{table.Schema}' and TABLE_NAME='{table.Name}';"; _sqltext = string.Format(_sqltext, table.Schema, table.Name); dbContext.Execute.ExecuteDataReader(dr => { DbFieldInfo fi = new DbFieldInfo { Oid = Convert.ToInt32(dr["ORDINAL_POSITION"]), Name = dr["COLUMN_NAME"].ToString(), Length = Convert.ToInt64(dr["LENGTEH"].ToString()), NotNull = dr["IS_NULLABLE"].ToString() == "NO", Comment = dr["COLUMN_COMMENT"].ToString(), Numeric_scale = Convert.ToInt32(dr["NUMERIC_SCALE"].ToString()), DbType = dr["DATA_TYPE"].ToString(), AutoIncrement = Convert.ToBoolean(dr["auto_increment"]) }; fi.CsType = MysqlType.SwitchToCSharp(fi.DbType); if (!fi.NotNull && fi.CsType != "string" && fi.CsType != "byte[]" && fi.CsType != "JToken") { fi.RelType = $"{fi.CsType}?"; } else { fi.RelType = fi.CsType; } if ((fi.RelType == "string" && fi.Length != 0 && fi.Length != 255) || (fi.Numeric_scale > 0) || (MysqlType.ContrastType(fi.DbType) == null)) { fi.DbTypeFull = dr["COLUMN_TYPE"].ToString(); } table.Fields.Add(fi); }, CommandType.Text, _sqltext); if (table.Type == TableType.Table) { GetPrimarykey(table); } }
private void SerializeField(TableInfo table, Type type) { var properties = MyStagingUtils.GetDbFields(type); foreach (var pi in properties) { var fi = new DbFieldInfo(); fi.Name = pi.Name; var customAttributes = pi.GetCustomAttributes(); var genericAttrs = customAttributes.Select(f => f.GetType()).ToArray(); var pk = pi.GetCustomAttribute <PrimaryKeyAttribute>(); fi.PrimaryKey = pk != null; if (fi.PrimaryKey) { fi.AutoIncrement = pk.AutoIncrement; } if (pi.PropertyType.Name == "Nullable`1") { fi.NotNull = false; fi.CsType = pi.PropertyType.GenericTypeArguments[0].Name; } else { fi.CsType = pi.PropertyType.Name; if (pi.PropertyType == typeof(string)) { fi.NotNull = fi.PrimaryKey || genericAttrs.Where(f => f == typeof(RequiredAttribute)).FirstOrDefault() != null; } else { fi.NotNull = pi.PropertyType.IsValueType; } } var columnAttribute = customAttributes.Where(f => f.GetType() == typeof(ColumnAttribute)).FirstOrDefault(); if (columnAttribute != null) { var colAttribute = ((ColumnAttribute)columnAttribute); fi.DbType = fi.DbTypeFull = colAttribute.TypeName; } else { fi.DbType = PgsqlType.GetDbType(fi.CsType.Replace("[]", "")); fi.DbTypeFull = GetFullDbType(fi); } fi.IsArray = fi.CsType.Contains("[]"); table.Fields.Add(fi); } }
/// <summary> /// 获取成员信息 /// </summary> protected virtual MemberInfo FindTypeMember(MemberInfo[] properties, DbFieldInfo dataInfo) { foreach (var item in properties) { if (item.Name.Equals(dataInfo.DataName, StringComparison.OrdinalIgnoreCase)) { return(item); } else if (item.Name.Equals(dataInfo.DataName.Replace("_", ""), StringComparison.OrdinalIgnoreCase)) { return(item); } } return(null); }
private static void Bind(object data, IDataRecord row, DbRecordInfo info) { var identityRecordInfo = info as DbIdentityRecordInfo; if (identityRecordInfo != null) { DbFieldInfo field = identityRecordInfo.PrimaryKey; object value = row[field.Name]; if (value == DBNull.Value) { if (field.DefaultValue != null) { value = field.DefaultValue; } } else { value = DbConverter.GetValue(field, value); } setValue(field, data, value); } int count = info.Fields.Length; for (int j = 0; j < count; j++) { DbFieldInfo field = info.Fields[j]; object value = row[field.Name]; if (value == DBNull.Value) { if (field.DefaultValue != null) { value = field.DefaultValue; } } else { value = DbConverter.GetValue(field, value); } setValue(field, data, value); // i++; } }
/// <summary> /// 获取实体的成员信息 /// </summary> /// <param name="entityType">实体类型</param> /// <param name="fieldInfo">数据字段信息</param> /// <returns></returns> protected virtual MemberInfo MatchEntityPropertyInfo(Type entityType, DbFieldInfo fieldInfo) { var properties = entityType.GetProperties(); foreach (var item in properties) { if (item.Name.Equals(fieldInfo.DataName, StringComparison.OrdinalIgnoreCase)) { return(item); } else if (item.Name.Equals(fieldInfo.DataName.Replace("_", ""), StringComparison.OrdinalIgnoreCase)) { return(item); } } return(null); }
/// <summary> /// Remove object from database /// </summary> /// <param name="data">an object with DbAttributes</param> /// <returns>true if one object has been removed</returns> public bool Delete(object data) { var info = DbAttributesManager.GetRecordInfo(data.GetType()); var identityRecordInfo = info as DbIdentityRecordInfo; if (identityRecordInfo != null) { DbFieldInfo primaryKey = identityRecordInfo.PrimaryKey; return(0 < Accessor.Delete( info.TableName, primaryKey.Name, primaryKey.GetValue(data))); } return(1 < DeleteByAllFields(data)); }
private string GetFullDbType(DbFieldInfo fi) { string fullType = null; if (fi.Length > 0) { if (fi.Length != 255 && fi.CsType == "String") { fullType = $"{fi.DbType}({fi.Length})"; } else if (fi.CsType != "String" && fi.Numeric_scale > 0) { fullType = $"{fi.DbType}({fi.Length},{fi.Numeric_scale})"; } } return(fullType); }
private Dictionary <string, DbFieldInfo> GetDbFieldInfo(LibDataAccess dataAccess, string tableName) { Dictionary <string, DbFieldInfo> dic = new Dictionary <string, DbFieldInfo>(); using (IDataReader reader = dataAccess.ExecuteDataReader(string.Format("select column_name,data_default,char_length from all_tab_columns where table_name='{0}'", tableName))) { do { while (reader.Read()) { if (!dic.ContainsKey(LibSysUtils.ToString(reader[0]))) { DbFieldInfo info = new DbFieldInfo(LibSysUtils.ToString(reader[1]), LibSysUtils.ToInt32(reader[2])); dic.Add(LibSysUtils.ToString(reader[0]), info); } } } while (reader.NextResult()); } return(dic); }
/// <summary> /// 根据数据实体特性解析出数据库表信息 /// </summary> /// <returns></returns> internal DbTableInfo AnalyzeTableInfo() { Type entityType = this.GetType(); TablePropertyAttribute tableProperty = Attribute.GetCustomAttribute(entityType, typeof(TablePropertyAttribute)) as TablePropertyAttribute; if (tableProperty == null) throw new Exception(string.Format("{0} class need a attribute named 'TableProperty'", entityType.Name)); DbTableInfo tableInfo = new DbTableInfo() { Name = tableProperty.TableName }; foreach (PropertyInfo p in entityType.GetProperties()) { object[] customAttributes = p.GetCustomAttributes(false); FieldPropertyAttribute fpa = customAttributes.OfType<FieldPropertyAttribute>().FirstOrDefault(); if (fpa == null) break; DbFieldInfo field = new DbFieldInfo() { Name = fpa.FieldName, Value = p.GetValue(this, null), IsKey = fpa.IsKey, IsNullable = fpa.IsNullable }; FieldValueAttribute fva = customAttributes.OfType<FieldValueAttribute>().FirstOrDefault(); if (fva == null) { field.ValueType = FieldValueType.String; field.DefaultValue = null; } else { field.ValueType = fva.ValueType; field.DefaultValue = fva.DefaultValue; } IgnoreUpdateAttribute iua = customAttributes.OfType<IgnoreUpdateAttribute>().FirstOrDefault(); if (iua == null) { field.IsIgnoreUpdate = false; } else { field.IsIgnoreUpdate = true; } tableInfo.Fields.Add(field); } return tableInfo; }
private static void setValue(DbFieldInfo field, object data, object value) { try { if (value == DBNull.Value) { field.SetValue(data, null); } else { Type type = DbConverter.GetType(field.FieldType); object convertedValue = Convert.ChangeType(value, type); field.SetValue(data, convertedValue); } } catch (Exception ex) { throw new NdbException("Can't set field value.\r\nField: " + field.Name + "\r\nValue: '" + value + "'\r\nError: " + ex.Message); } }
private bool HasFieldChanged(DataColumn col, string dataType, Dictionary <string, DbFieldInfo> defaultDic) { bool hasDiff = false; LibDataType tempDataType = (LibDataType)col.ExtendedProperties[FieldProperty.DataType]; string dbType = ReturnOracleType(tempDataType); string curDefaultValue = string.Empty; bool isText = tempDataType == LibDataType.Text || tempDataType == LibDataType.NText || tempDataType == LibDataType.Binary; DbFieldInfo dbFieldInfo = defaultDic[col.ColumnName]; if (isText) { curDefaultValue = LibSysUtils.ToString(col.DefaultValue); } else if (tempDataType == LibDataType.Boolean) { if ((bool)col.DefaultValue) { curDefaultValue = "1"; } } else { curDefaultValue = col.DefaultValue.ToString(); } if (string.Compare(dbType, dataType, true) != 0 || (isText && col.MaxLength != dbFieldInfo.Length)) { hasDiff = true; } else { string defaultValue = string.Empty; defaultValue = dbFieldInfo.DefaultValue; if (curDefaultValue != defaultValue) { hasDiff = true; } } return(hasDiff); }
internal override void CreateTable(DbRecordInfo info) { StringBuilder sb = new StringBuilder("CREATE TABLE " + info.TableName + "("); DbIdentityRecordInfo identityRecordInfo = info as DbIdentityRecordInfo; if (identityRecordInfo != null) { DbFieldInfo key = identityRecordInfo.PrimaryKey; if (key.FieldType == typeof(Guid)) { sb.Append(GetDefinition(key) + " NOT NULL PRIMARY KEY UNIQUE"); } else { sb.Append(GetDefinition(key) + " NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE"); } sb.Append(','); } foreach (DbFieldInfo field in info.Fields) { sb.Append(GetDefinition(field)); sb.Append(','); } sb.Remove(sb.Length - 1, 1); sb.Append(")"); string query = sb.ToString(); ExecuteNonQuery(query); createTriggers(info); }
internal override void CreateTable(DbRecordInfo info) { string postQueries = ""; /*; * CREATE TABLE tablename ( * colname integer NOT NULL DEFAULT nextval('tablename_colname_seq') * ); * ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;*/ StringBuilder sb = new StringBuilder("CREATE TABLE " + info.TableName + " ("); DbIdentityRecordInfo identityRecordInfo = info as DbIdentityRecordInfo; if (identityRecordInfo != null) { DbFieldInfo key = identityRecordInfo.PrimaryKey; if (key.FieldType == typeof(Guid)) { sb.Append(GetDefinition(key) + " NOT NULL"); sb.Append(','); } else { string sequenceName = string.Format("{0}_{1}_seq", info.TableName, key.Name); sb.Insert(0, "CREATE SEQUENCE " + sequenceName + ";"); postQueries = string.Format("ALTER SEQUENCE {0}_{1}_seq OWNED BY {0}.{1};", info.TableName, key.Name); sb.Append(GetDefinition(key) + " NOT NULL DEFAULT nextval('" + sequenceName + "'::regclass)"); sb.Append(','); } } foreach (DbFieldInfo field in info.Fields) { sb.Append(GetDefinition(field)); sb.Append(','); } string[] keys = getPrimaryKeys(info); sb.AppendFormat("PRIMARY KEY ({0}), UNIQUE ({0})", String.Join(",", keys)); // sb.AppendFormat("CONSTRAINT \"PK_{1}\" PRIMARY KEY ({0})", String.Join(",", keys), info.TableName); // sb.AppendFormat("CONSTRAINT \"U_{1}\" UNIQUE ({0})", String.Join(",", keys), info.TableName); //Process indexes DbIndexesInfo indexes = DbAttributesManager.GetIndexes(info.Fields); ProcessIndexes(sb, indexes.Unique, ",UNIQUE ({0})"); // ProcessIndexes(sb, indexes.Indexes, ",KEY {1} ({0})"); // ProcessIndexes(sb, indexes.FullText, ",FULLTEXT KEY {1} ({0})"); //process foreign keys foreach (KeyValuePair <Type, DbFieldInfo> key in info.ForeignKeys) { DbIdentityRecordInfo ri = DbAttributesManager.GetRecordInfo(key.Key) as DbIdentityRecordInfo; if (ri == null) { throw new NdbException("Only DbIdentityRecord objects can be used as Foreign Keys"); } sb.AppendFormat( ",FOREIGN KEY ({1}) REFERENCES {0} ({2}) ON DELETE CASCADE ON UPDATE CASCADE" , ri.TableName , key.Value.Name , ri.PrimaryKey.Name); } sb.Append(");"); sb.Append(postQueries); string query = sb.ToString(); ExecuteNonQuery(query); }
private void SerializeField(TableInfo table, Type type) { var properties = MyStagingUtils.GetDbFields(type); foreach (var pi in properties) { var fi = new DbFieldInfo(); fi.Name = pi.Name; var customAttributes = pi.GetCustomAttributes(); var genericAttrs = customAttributes.Select(f => f.GetType()).ToArray(); if (pi.PropertyType.Name == "Nullable`1") { fi.NotNull = false; fi.CsType = pi.PropertyType.GenericTypeArguments[0].Name; } else { fi.CsType = pi.PropertyType.Name; if (pi.PropertyType == typeof(string)) { fi.NotNull = genericAttrs.Where(f => f == typeof(RequiredAttribute) || f == typeof(PrimaryKeyAttribute)).FirstOrDefault() != null; } else { fi.NotNull = pi.PropertyType.IsValueType; } } fi.PrimaryKey = genericAttrs.Where(f => f == typeof(PrimaryKeyAttribute)).FirstOrDefault() != null; if (fi.PrimaryKey) { var pk = pi.GetCustomAttribute <PrimaryKeyAttribute>(); fi.AutoIncrement = pk.AutoIncrement; } var columnAttribute = customAttributes.Where(f => f.GetType() == typeof(ColumnAttribute)).FirstOrDefault(); if (columnAttribute != null) { var colAttribute = ((ColumnAttribute)columnAttribute); fi.DbType = fi.DbTypeFull = colAttribute.TypeName; if (colAttribute.TypeName != "char(36)" && colAttribute.TypeName != "tinyint(1)") { var zero = colAttribute.TypeName.IndexOf("("); if (zero > 0) { fi.DbType = colAttribute.TypeName.Substring(0, zero); } } } else { fi.DbTypeFull = GetFullDbType(fi); fi.DbType = MysqlType.GetDbType(fi.CsType); if (fi.DbType == "varchar" || fi.DbType == "char") { fi.DbTypeFull = $"{fi.DbType}(255)"; } } table.Fields.Add(fi); } }
private void GetFields(TableInfo table) { string _sqltext = @"SELECT a.oid ,c.attnum as num ,c.attname as field ,c.attnotnull as notnull ,d.description as comment ,(case when e.typcategory ='G' then e.typname when e.typelem = 0 then e.typname else e2.typname end) as type ,(case when e.typelem = 0 then e.typtype else e2.typtype end) as data_type ,COALESCE(( case when (case when e.typcategory ='G' then e.typname when e.typelem = 0 then e.typname else e2.typname end) in ('numeric','int2','int4','int8','float4','float8') then f.numeric_precision when (case when e.typcategory ='G' then e.typname when e.typelem = 0 then e.typname else e2.typname end) in ('timestamp','timestamptz','interval','time','date','timetz') then f.datetime_precision when f.character_maximum_length is null then 0 else f.character_maximum_length end ),0) as length ,COALESCE(( case when (case when e.typcategory ='G' then e.typname when e.typelem = 0 then e.typname else e2.typname end) in ('numeric') then f.numeric_scale else 0 end ),0) numeric_scale ,e.typcategory ,f.udt_schema ,f.column_default from pg_class a inner join pg_namespace b on a.relnamespace=b.oid inner join pg_attribute c on attrelid = a.oid LEFT OUTER JOIN pg_description d ON c.attrelid = d.objoid AND c.attnum = d.objsubid and c.attnum > 0 inner join pg_type e on e.oid=c.atttypid left join pg_type e2 on e2.oid=e.typelem inner join information_schema.columns f on f.table_schema = b.nspname and f.table_name=a.relname and column_name = c.attname WHERE b.nspname='{0}' and a.relname='{1}';"; _sqltext = string.Format(_sqltext, table.Schema, table.Name); dbContext.Execute.ExecuteDataReader(dr => { DbFieldInfo fi = new DbFieldInfo { Oid = Convert.ToInt32(dr["oid"]), Name = dr["field"].ToString(), Length = Convert.ToInt32(dr["length"].ToString()), NotNull = Convert.ToBoolean(dr["notnull"]), Comment = dr["comment"].ToString(), Numeric_scale = Convert.ToInt32(dr["numeric_scale"].ToString()), ColumnDefault = dr["column_default"].ToString(), }; var udt_schema = dr["udt_schema"].ToString(); var typcategory = dr["typcategory"].ToString(); var dbtype = dr["type"].ToString(); fi.DbType = typcategory == "E" ? udt_schema + "." + dbtype : dbtype; fi.IsArray = typcategory == "A"; fi.CsType = PgsqlType.SwitchToCSharp(dbtype); fi.AutoIncrement = fi.ColumnDefault != null && fi.ColumnDefault.StartsWith("nextval('") && fi.ColumnDefault.EndsWith("'::regclass)"); string _notnull = ""; if ( fi.CsType != "string" && fi.CsType != "byte[]" && fi.CsType != "JToken" && !fi.IsArray && fi.CsType != "System.Net.IPAddress" && fi.CsType != "System.Net.NetworkInformation.PhysicalAddress" && fi.CsType != "System.Xml.Linq.XDocument" && fi.CsType != "System.Collections.BitArray" && fi.CsType != "object" ) { _notnull = fi.NotNull ? "" : "?"; } string _array = fi.IsArray ? "[]" : ""; fi.RelType = $"{fi.CsType}{_notnull}{_array}"; if (fi.RelType == "string" && (fi.Length != 0 && fi.Length != 255)) { fi.DbTypeFull = $"{fi.DbType}({fi.Length})"; } else if (fi.Numeric_scale > 0) { fi.DbTypeFull = ($"{fi.DbType}({fi.Length},{fi.Numeric_scale})"); } else if (PgsqlType.ContrastType(fi.DbType) == null) { fi.DbTypeFull = fi.DbType; } table.Fields.Add(fi); }, CommandType.Text, _sqltext); if (table.Type == TableType.Table) { GetPrimarykey(table); } }
public static object SetValue(DbFieldInfo field, object value) { return(field.IsDiffersFromDatabaseType ? convertData(field.DbType, value) : value); }
internal string GetSqlType(DbFieldInfo fieldInfo) { Type type = DbConverter.GetType(fieldInfo.FieldType); return(GetSqlType(type, fieldInfo.Size)); }
/// <summary> /// 创建动态方法 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="record"></param> /// <returns></returns> private Func <IDataRecord, T> CreateTypeSerializerHandler <T>(IDataRecord record) { var type = typeof(T); var methodName = $"Serializer{Guid.NewGuid():N}"; var dynamicMethod = new DynamicMethod(methodName, type, new Type[] { typeof(IDataRecord) }, type, true); var generator = dynamicMethod.GetILGenerator(); LocalBuilder local = generator.DeclareLocal(type); var dataInfos = new DbFieldInfo[record.FieldCount]; for (int i = 0; i < record.FieldCount; i++) { var dataname = record.GetName(i); var datatype = record.GetFieldType(i); var typename = record.GetDataTypeName(i); dataInfos[i] = new DbFieldInfo(i, typename, datatype, dataname); } if (type == typeof(object) || dataInfos.Length == 1 && (type.IsValueType || type == typeof(string))) { var convertMethod = FindTypeMethod(type, type); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldc_I4, 0); if (convertMethod.IsVirtual) { generator.Emit(OpCodes.Callvirt, convertMethod); } else { generator.Emit(OpCodes.Call, convertMethod); } if (type == typeof(object) && convertMethod.ReturnType.IsValueType) { generator.Emit(OpCodes.Box, convertMethod.ReturnType); } generator.Emit(OpCodes.Stloc, local); generator.Emit(OpCodes.Ldloc, local); generator.Emit(OpCodes.Ret); return(dynamicMethod.CreateDelegate(typeof(Func <IDataRecord, T>)) as Func <IDataRecord, T>); } var constructor = FindConstructor(type); if (constructor.GetParameters().Length > 0) { var parameters = constructor.GetParameters(); var locals = new LocalBuilder[parameters.Length]; for (int i = 0; i < locals.Length; i++) { locals[i] = generator.DeclareLocal(parameters[i].ParameterType); } for (int i = 0; i < locals.Length; i++) { var item = FindTypeParameter(dataInfos, parameters[i]); if (item == null) { continue; } var convertMethod = FindTypeMethod(type, parameters[i].ParameterType); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldc_I4, item.Ordinal); if (convertMethod.IsVirtual) { generator.Emit(OpCodes.Callvirt, convertMethod); } else { generator.Emit(OpCodes.Call, convertMethod); } generator.Emit(OpCodes.Stloc, locals[i]); } for (int i = 0; i < locals.Length; i++) { generator.Emit(OpCodes.Ldloc, locals[i]); } generator.Emit(OpCodes.Newobj, constructor); generator.Emit(OpCodes.Stloc, local); generator.Emit(OpCodes.Ldloc, local); generator.Emit(OpCodes.Ret); return(dynamicMethod.CreateDelegate(typeof(Func <IDataRecord, T>)) as Func <IDataRecord, T>); } else { var properties = type.GetProperties(); generator.Emit(OpCodes.Newobj, constructor); generator.Emit(OpCodes.Stloc, local); foreach (var item in dataInfos) { var property = FindTypeMember(properties, item) as PropertyInfo; if (property == null) { continue; } var convertMethod = FindTypeMethod(type, property.PropertyType); if (convertMethod == null) { continue; } int i = record.GetOrdinal(item.DataName); generator.Emit(OpCodes.Ldloc, local); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldc_I4, i); if (convertMethod.IsVirtual) { generator.Emit(OpCodes.Callvirt, convertMethod); } else { generator.Emit(OpCodes.Call, convertMethod); } generator.Emit(OpCodes.Callvirt, property.GetSetMethod()); } generator.Emit(OpCodes.Ldloc, local); generator.Emit(OpCodes.Ret); return(dynamicMethod.CreateDelegate(typeof(Func <IDataRecord, T>)) as Func <IDataRecord, T>); } }
/// <summary> /// Constructor /// </summary> /// <param name="primaryKey">The primary key.</param> /// <param name="isDbGeneratedPrimaryKey">if set to <c>true</c> marks field as db generated.</param> public DbIdentityRecordInfo(DbFieldInfo primaryKey, bool isDbGeneratedPrimaryKey) { PrimaryKey = primaryKey; IsDbGeneratedPrimaryKey = isDbGeneratedPrimaryKey; }
/// <summary> /// GetFieldList - gather an array of all fields in this table or view /// </summary> /// <param name="p_Conn">an open database connection</param> /// <returns></returns> internal void CollectFields(IDbConnection p_Conn) { string sqlQuery = "SELECT c.Column_Name, c.Column_Default, c.Is_Nullable, " + " c.Data_Type, c.Character_Maximum_Length, " + " c.Numeric_Precision, c.Numeric_Scale " + " FROM Information_Schema.Columns c " + " WHERE Table_Name = @Table " + " ORDER BY Ordinal_Position ; "; List<DbFieldInfo> list = new List<DbFieldInfo>(); DbFieldInfo dbFieldInfo = null; int i; // Connect to database, collect list of tables IDbCommand cmd = null; IDataReader reader = null; string Column_Name; string Column_Default; string Is_Nullable; bool bIs_Nullable; int Character_Maximum_Length; int Numeric_Precision; int Numeric_Scale; string Data_Type; try { cmd = p_Conn.CreateCommand(); cmd.CommandType = CommandType.Text; cmd.CommandText = sqlQuery; IDbDataParameter p = cmd.CreateParameter(); p.ParameterName = "Table"; p.Value = _TableName; cmd.Parameters.Add(p); reader = cmd.ExecuteReader(); while (reader.Read()) { // Debug.WriteLine("Field: " + reader.GetString(0)); i = 0; Column_Name = reader.IsDBNull(i) ? "" : reader.GetString(i); i++; Column_Default = reader.IsDBNull(i) ? "" : reader.GetString(i); i++; Is_Nullable = reader.IsDBNull(i) ? "" : reader.GetString(i); i++; Data_Type = reader.IsDBNull(i) ? "" : reader.GetString(i); i++; Character_Maximum_Length = reader.IsDBNull(i) ? 0 : reader.GetInt32(i); i++; Numeric_Precision = reader.IsDBNull(i) ? (byte)0 : reader.GetByte(i); i++; Numeric_Scale = reader.IsDBNull(i) ? 0 : reader.GetInt32(i); i++; bIs_Nullable = Is_Nullable.Equals("YES"); dbFieldInfo = new DbFieldInfo(Column_Name, Column_Default, bIs_Nullable, Character_Maximum_Length, Numeric_Precision, Numeric_Scale, Data_Type); list.Add(dbFieldInfo); } } finally { if (reader != null) reader.Close(); if (cmd != null) cmd.Dispose(); } _DbFieldInfo = list.ToArray(); // identify primary key CollectPrimaryKeys(p_Conn); // load foreign keys and associate them to dbFieldInfo objects CollectForeignKeys(p_Conn); // load related tables that refer to this table via a foreign key CollectDependentTables(p_Conn); }
public static string GetRealType(DbFieldInfo fi) { var realType = fi.DbTypeFull ?? fi.DbType; return(realType == "varchar" || realType == "char" ? realType + "(255)" : realType); }
/// <summary> /// 获取映射实体成员的转换方法 /// </summary> /// <param name="entityType">实体类型</param> /// <param name="entityMemberType">实体的成员类型</param> /// <param name="fieldInfo">数据库字信息</param> /// <returns></returns> protected virtual MethodInfo MatchDataRecordConvertMethod(Type entityType, Type entityMemberType, DbFieldInfo fieldInfo) { if (GetUnderlyingType(entityMemberType) == typeof(bool)) { return(!IsNullableType(entityMemberType) ? DataRecordConvertMethods.ToBooleanMethod : DataRecordConvertMethods.ToBooleanNullableMethod); } if (GetUnderlyingType(entityMemberType).IsEnum) { return(!IsNullableType(entityMemberType) ? DataRecordConvertMethods.ToEnumMethod.MakeGenericMethod(entityMemberType) : DataRecordConvertMethods.ToEnumNullableMethod.MakeGenericMethod(GetUnderlyingType(entityMemberType))); } if (GetUnderlyingType(entityMemberType) == typeof(char)) { return(!IsNullableType(entityMemberType) ? DataRecordConvertMethods.ToCharMethod : DataRecordConvertMethods.ToCharNullableMethod); } if (entityMemberType == typeof(string)) { return(DataRecordConvertMethods.ToStringMethod); } if (GetUnderlyingType(entityMemberType) == typeof(Guid)) { return(!IsNullableType(entityMemberType) ? DataRecordConvertMethods.ToGuidMethod : DataRecordConvertMethods.ToGuidNullableMethod); } if (GetUnderlyingType(entityMemberType) == typeof(DateTime)) { return(!IsNullableType(entityMemberType) ? DataRecordConvertMethods.ToDateTimeMethod : DataRecordConvertMethods.ToDateTimeNullableMethod); } if (GetUnderlyingType(entityMemberType) == typeof(byte) || GetUnderlyingType(entityMemberType) == typeof(sbyte)) { return(!IsNullableType(entityMemberType) ? DataRecordConvertMethods.ToByteMethod : DataRecordConvertMethods.ToByteNullableMethod); } if (GetUnderlyingType(entityMemberType) == typeof(short) || GetUnderlyingType(entityMemberType) == typeof(ushort)) { return(!IsNullableType(entityMemberType) ? DataRecordConvertMethods.ToIn16Method : DataRecordConvertMethods.ToIn16NullableMethod); } if (GetUnderlyingType(entityMemberType) == typeof(int) || GetUnderlyingType(entityMemberType) == typeof(uint)) { return(!IsNullableType(entityMemberType) ? DataRecordConvertMethods.ToIn32Method : DataRecordConvertMethods.ToIn32NullableMethod); } if (GetUnderlyingType(entityMemberType) == typeof(long) || GetUnderlyingType(entityMemberType) == typeof(ulong)) { return(!IsNullableType(entityMemberType) ? DataRecordConvertMethods.ToIn64Method : DataRecordConvertMethods.ToIn64NullableMethod); } if (GetUnderlyingType(entityMemberType) == typeof(float)) { return(!IsNullableType(entityMemberType) ? DataRecordConvertMethods.ToFloatMethod : DataRecordConvertMethods.ToFloatNullableMethod); } if (GetUnderlyingType(entityMemberType) == typeof(double)) { return(!IsNullableType(entityMemberType) ? DataRecordConvertMethods.ToDoubleMethod : DataRecordConvertMethods.ToDoubleNullableMethod); } if (GetUnderlyingType(entityMemberType) == typeof(decimal)) { return(!IsNullableType(entityMemberType) ? DataRecordConvertMethods.ToDecimalMethod : DataRecordConvertMethods.ToDecimalNullableMethod); } return(DataRecordConvertMethods.ToObjectMethod); }