/// <summary> /// Get Internal type of IList /// </summary> /// <param name="type"></param> /// <returns></returns> public static Type GetActualType(this Type type) { if (CachedActualType.ContainsKey(type)) { return(CachedActualType[type]); } if (type.GetTypeInfo().IsArray) { CachedActualType.TryAdd(type, type.GetElementType()); } else if (type.GenericTypeArguments.Any()) { CachedActualType.TryAdd(type, type.GenericTypeArguments.First()); } else if (type.FullName?.Contains("List`1") ?? false) { CachedActualType.TryAdd(type, type.GetRuntimeProperty("Item").PropertyType); } else { CachedActualType.TryAdd(type, type); } return(CachedActualType.Get(type)); }
internal static bool GetField(this FieldInfo field, Custom_ValueType <string, IFastDeepClonerProperty> properties) { if (!properties.ContainsKey(field.Name)) { return(properties.TryAdd(field.Name, new FastDeepClonerProperty(field))); } return(true); }
protected object VisitMember(MemberExpression m, bool columnOnly) { try { if (m.Expression != null && m.Expression.NodeType == ExpressionType.Constant && (_overridedNodeType == null)) { VisitConstantFixed(m.Expression as ConstantExpression, m.Member?.Name); return(m); } else if (m.Expression != null && (m.Expression.NodeType == ExpressionType.Parameter || (m.ToString().EndsWith(".HasValue") && m.Expression.NodeType == ExpressionType.MemberAccess)) && (_overridedNodeType == null)) { var hasValueAttr = m.ToString().EndsWith(".HasValue"); _overridedNodeType = null; var cl = hasValueAttr ? (m.Expression as MemberExpression).Expression.Type : m.Expression.Type; var prop = DeepCloner.GetFastDeepClonerProperties(cl).First(x => x.Name == (hasValueAttr ? (m.Expression as MemberExpression).Member.Name : m.Member.Name)); var name = prop.GetPropertyName(); var table = cl.TableName(); var columnName = string.Format("[{0}].[{1}]", table, name).CleanValidSqlName(DataBaseTypes); var dataEncode = prop.GetCustomAttribute <DataEncode>(); if (columnOnly) { return(columnName); } bool isNot = sb.ToString().EndsWith("NOT "); if (prop.PropertyType.IsEnum && prop.ContainAttribute <Stringify>()) { if (!SavedTypes.ContainsKey(prop.FullName)) { SavedTypes.TryAdd(prop.FullName, prop.PropertyType); } columnName += stringyFy.Replace("#", prop.FullName); } if (isNot) { if (!hasValueAttr) { columnName = $"(CASE WHEN { columnName } = 0 THEN 1 ELSE 0 END) {boolString.Replace("#", "0")}"; } else { columnName = $"(CASE WHEN {columnName} IS NULL THEN 1 ELSE 0 END) {boolString.Replace("#", "0")}"; } } else if (hasValueAttr) { columnName = $"(CASE WHEN {columnName} IS NULL THEN 0 ELSE 1 END) {boolString.Replace("#", "1")}"; } else if (prop.PropertyType == typeof(bool) || prop.PropertyType == typeof(bool?)) { columnName = columnName + boolString.Replace("#", "1"); } if (dataEncode != null) { columnName = columnName + dataEncodeString.Replace("#", dataEncode.Key + "|" + ((int)dataEncode.KeySize).ToString()); } sb.Append(columnName); return(m); } else if (m.Expression != null && (m.Expression.NodeType == ExpressionType.MemberAccess)) { _overridedNodeType = null; var key = string.Join("", m.ToString().Split('.').Take(m.ToString().Split('.').Length - 1)); var cl = m.Expression.Type; var prop = DeepCloner.GetFastDeepClonerProperties(cl).First(x => x.Name == m.Member.Name); var name = prop.GetPropertyName(); var table = cl.TableName(); var randomTableName = JoinClauses.ContainsKey(key) ? JoinClauses[key].Item1 : RandomKey(); var primaryId = DeepCloner.GetFastDeepClonerProperties(cl).First(x => x.ContainAttribute <PrimaryKey>()).GetPropertyName(); var columnName = string.Format("[{0}].[{1}]", randomTableName, name).CleanValidSqlName(DataBaseTypes); if (columnOnly) { return(columnName); } sb.Append(columnName); if (JoinClauses.ContainsKey(key)) { return(m); } // Ok lets build inner join var parentType = (m.Expression as MemberExpression).Expression.Type; var parentTable = parentType.TableName(); prop = DeepCloner.GetFastDeepClonerProperties(parentType).FirstOrDefault(x => x.ContainAttribute <ForeignKey>() && x.GetCustomAttribute <ForeignKey>().Type == cl); var v = ""; if (prop != null) { v += string.Format("LEFT JOIN [{0}] {1} ON [{2}].[{3}] = [{4}].[{5}]", table, randomTableName, randomTableName, primaryId, parentTable, prop.GetPropertyName()).CleanValidSqlName(DataBaseTypes); } else { prop = DeepCloner.GetFastDeepClonerProperties(cl).FirstOrDefault(x => x.ContainAttribute <ForeignKey>() && x.GetCustomAttribute <ForeignKey>().Type == parentType); if (prop != null) { v += string.Format("LEFT JOIN [{0}] {1} ON [{2}].[{3}] = [{4}].[{5}]", table, randomTableName, randomTableName, prop.GetPropertyName(), parentTable, primaryId).CleanValidSqlName(DataBaseTypes); } } if (string.IsNullOrEmpty(v)) { sb = sb.Remove(sb.Length - columnName.Length, columnName.Length); sb.Append(ValuetoSql(GetValue(m))); } else { JoinClauses.TryAdd(key, new Tuple <string, string>(randomTableName, v)); } return(m); } else if (m.Expression != null && _overridedNodeType == ExpressionType.MemberAccess) { _overridedNodeType = null; var key = string.Join("", m.ToString().Split('.').Take(m.ToString().Split('.').Length - 1)); var cl = m.Expression.Type; var prop = DeepCloner.GetFastDeepClonerProperties(cl).First(x => x.Name == m.Member.Name); var table = cl.TableName(); var randomTableName = JoinClauses.ContainsKey(key) ? JoinClauses[key].Item1 : RandomKey(); var primaryId = DeepCloner.GetFastDeepClonerProperties(cl).First(x => x.ContainAttribute <PrimaryKey>()).GetPropertyName(); if (JoinClauses.ContainsKey(key)) { return(m); } // Ok lets build inner join var parentType = (m as MemberExpression).Type.GetActualType(); var parentTable = parentType.TableName(); prop = DeepCloner.GetFastDeepClonerProperties(parentType).FirstOrDefault(x => x.ContainAttribute <ForeignKey>() && x.GetCustomAttribute <ForeignKey>().Type == cl); var v = ""; if (prop != null) { v += string.Format("INNER JOIN [{0}] {1} ON [{2}].[{3}] = [{4}].[{5}]", parentTable, randomTableName, table, primaryId, randomTableName, prop.GetPropertyName()).CleanValidSqlName(DataBaseTypes); } else { throw new NotSupportedException(string.Format("Expression STRUCTURE IS NOT SUPPORTED MEMBER{0} for EntityWorker", m.Member.Name)); } if (!string.IsNullOrEmpty(v)) { JoinClauses.TryAdd(key, new Tuple <string, string>(randomTableName, v)); } return(m); } } catch { throw new NotSupportedException(string.Format("Expression '{0}' is not supported", m.ToString())); } if (m.Type.IsInternalType() && m.Expression.NodeType == ExpressionType.Call) { sb.Append(ValuetoSql(Expression.Lambda(m).Compile().DynamicInvoke())); return(m); } throw new NotSupportedException(string.Format("The member '{0}' is not supported", m.Member.Name)); }
internal static DbCommandExtended ProcessSql(this IRepository repository, IDbConnection connection, IDbTransaction tran, string sql) { var i = 1; var dicCols = new Custom_ValueType <string, Tuple <object, SqlDbType> >(); MatchCollection matches = null; while ((matches = stringExp.Matches(sql)).Count > 0) { var exp = matches[0]; var col = "@CO" + i + "L"; object str = exp.Value.TrimEnd(']').Substring(@"String\[".Length - 1); sql = sql.Remove(exp.Index, exp.Value.Length); sql = sql.Insert(exp.Index, col); dicCols.TryAdd(col, new Tuple <object, SqlDbType>(str.ConvertValue <string>(), SqlDbType.NVarChar)); i++; } while ((matches = dateExp.Matches(sql)).Count > 0) { var exp = matches[0]; var col = "@CO" + i + "L"; object str = exp.Value.TrimEnd(']').Substring(@"Date\[".Length - 1); sql = sql.Remove(exp.Index, exp.Value.Length); sql = sql.Insert(exp.Index, col); dicCols.TryAdd(col, new Tuple <object, SqlDbType>(str.ConvertValue <DateTime>(), SqlDbType.DateTime)); i++; } while ((matches = guidExp.Matches(sql)).Count > 0) { var exp = matches[0]; var col = "@CO" + i + "L"; object str = exp.Value.TrimEnd(']').Substring(@"Guid\[".Length - 1); sql = sql.Remove(exp.Index, exp.Value.Length); sql = sql.Insert(exp.Index, col); dicCols.TryAdd(col, new Tuple <object, SqlDbType>(str.ConvertValue <Guid?>(), SqlDbType.UniqueIdentifier)); i++; } sql = sql.CleanValidSqlName(repository.DataBaseTypes); DbCommand cmd = null; if (repository.DataBaseTypes == DataBaseTypes.Mssql) { cmd = tran != null ? new SqlCommand(sql, connection as SqlConnection, tran as SqlTransaction) : new SqlCommand(sql, connection as SqlConnection); } else if (repository.DataBaseTypes == DataBaseTypes.Sqllight) { cmd = tran == null ? new SQLiteCommand(sql, connection as SQLiteConnection) : new SQLiteCommand(sql, connection as SQLiteConnection, tran as SQLiteTransaction); } else { cmd = tran == null ? new NpgsqlCommand(sql, connection as NpgsqlConnection) : new NpgsqlCommand(sql, connection as NpgsqlConnection, tran as NpgsqlTransaction); } var dbCommandExtended = new DbCommandExtended(cmd, repository); foreach (var dic in dicCols) { repository.AddInnerParameter(dbCommandExtended, dic.Key, dic.Value.Item1, dic.Value.Item2); } return(dbCommandExtended); }
internal static IList DataReaderConverter(Transaction.Transaction repository, IDataReader reader, DbCommandExtended command, Type type) { var tType = type.GetActualType(); var attachable = tType.GetPrimaryKey() != null; var baseListType = typeof(List <>); var listType = baseListType.MakeGenericType(tType); var iList = DeepCloner.CreateInstance(listType) as IList; var props = DeepCloner.GetFastDeepClonerProperties(tType); try { var colNames = new Custom_ValueType <int, string>(); var pp = new Custom_ValueType <int, FastDeepCloner.IFastDeepClonerProperty>(); while (reader.Read()) { object item = null; object clItem = null; item = DeepCloner.CreateInstance(tType); clItem = attachable ? DeepCloner.CreateInstance(tType) : null; var col = 0; while (col < reader.FieldCount) { string columnName; if (colNames.ContainsKey(col)) { columnName = colNames[col]; } else { columnName = reader.GetName(col); colNames.TryAdd(col, columnName); } var value = reader[columnName]; IFastDeepClonerProperty prop; if (!pp.ContainsKey(col)) { prop = DeepCloner.GetProperty(tType, columnName); if (prop == null) { prop = props.FirstOrDefault(x => string.Equals(x.GetPropertyName(), columnName, StringComparison.CurrentCultureIgnoreCase) || x.GetPropertyName().ToLower() == columnName); } pp.TryAdd(col, prop); } else { prop = pp[col]; } if (prop != null && value != DBNull.Value && value != null && prop.CanRead) { if (value as byte[] != null && prop.PropertyType.FullName.Contains("Guid")) { value = new Guid(value as byte[]); } var dataEncode = prop.GetCustomAttribute <DataEncode>(); if (prop.ContainAttribute <ToBase64String>()) { if (value.ConvertValue <string>().IsBase64String()) { value = MethodHelper.DecodeStringFromBase64(value.ConvertValue <string>()); } else { value = MethodHelper.ConvertValue(value, prop.PropertyType); } } else if (dataEncode != null) { value = new DataCipher(dataEncode.Key, dataEncode.KeySize).Decrypt(value.ConvertValue <string>()); } else if (prop.ContainAttribute <JsonDocument>()) { value = value?.ToString().FromJson(prop.PropertyType); } else if (prop.ContainAttribute <XmlDocument>()) { value = value?.ToString().FromXml(); } else { value = MethodHelper.ConvertValue(value, prop.PropertyType); } prop.SetValue(item, value); if (attachable) { prop.SetValue(clItem, value); } } col++; } if (clItem != null && !(repository?.IsAttached(clItem) ?? true)) { repository?.AttachNew(clItem); } iList.Add(item); } } catch (Exception e) { throw e; } finally { reader.Close(); reader.Dispose(); if (repository.OpenedDataReaders.ContainsKey(reader)) { repository.OpenedDataReaders.Remove(reader); } } return(iList); }