private static ISelect <T1> IncludeLevel <T1>(this ISelect <T1> select, int level, TableRefTree tree, ParameterExpression parameterExpression = null, MemberExpression bodyExpression = null) { var includeMethod = select.GetType().GetMethod("Include"); var includeManyMethod = select.GetType().GetMethod("IncludeMany"); parameterExpression ??= Expression.Parameter(tree.TableInfo.Type, "t"); foreach (var sub in tree.Subs) { switch (sub.TableRef.RefType) { case TableRefType.ManyToOne: case TableRefType.OneToOne: { var body = bodyExpression == null?Expression.Property(parameterExpression, sub.TableRef.Property) : Expression.Property(bodyExpression, sub.TableRef.Property); if (sub.Subs.Count == 0) { var funcType = typeof(Func <,>).MakeGenericType(parameterExpression.Type, sub.TableRef.RefEntityType); var navigateSelector = Expression.Lambda(funcType, body, parameterExpression); includeMethod.MakeGenericMethod(sub.TableRef.RefEntityType).Invoke(select, new object[] { navigateSelector }); } else { select.IncludeLevel(level, sub, parameterExpression, body); } } break; case TableRefType.ManyToMany: case TableRefType.OneToMany: { var body = bodyExpression == null?Expression.Property(parameterExpression, sub.TableRef.Property) : Expression.Property(bodyExpression, sub.TableRef.Property); object then = null; if (sub.Subs.Count > 0) { //var thenSelectType = select.GetType().GetGenericTypeDefinition().MakeGenericType(sub.TableRef.RefEntityType); var thenSelectType = typeof(ISelect <>).MakeGenericType(sub.TableRef.RefEntityType); var thenType = typeof(Action <>).MakeGenericType(thenSelectType); var thenParameter = Expression.Parameter(thenSelectType, "then"); var thenMethod = typeof(FreeSql_1113_Extensions).GetMethod(nameof(IncludeLevel)).MakeGenericMethod(sub.TableRef.RefEntityType); var thenLevelConst = Expression.Constant(level - sub.Level + 1); var thenBody = Expression.Call(null, thenMethod, thenParameter, thenLevelConst); var thenExpression = Expression.Lambda(thenType, thenBody, thenParameter); then = thenExpression.Compile(); } var funcType = typeof(Func <,>).MakeGenericType(parameterExpression.Type, typeof(IEnumerable <>).MakeGenericType(sub.TableRef.RefEntityType)); var navigateSelector = Expression.Lambda(funcType, body, parameterExpression); includeManyMethod.MakeGenericMethod(sub.TableRef.RefEntityType).Invoke(select, new object[] { navigateSelector, then }); } break; } } return(select); }
public static TableRefTree GetTableRefTree <T1>(ISelect <T1> select, int maxLevel, string[] properties = null) { var orm = select.GetType().GetField("_orm").GetValue(select) as IFreeSql; var tableInfo = orm.CodeFirst.GetTableByEntity(typeof(T1)); var tree = new TableRefTree() { Level = 1, TableInfo = tableInfo, }; tree.Subs = GetTableRefTree(orm, tree, maxLevel, properties).ToList(); return(tree); }
public static SqlCommand GetStoredProcedureCommand(ISelect entity, OptionsQueryZero options = null) { Table table = entity.GetType().GetCustomAttribute <Table>(); string nameTable = table == null?entity.GetType().Name : table.Name; SqlCommand command = new SqlCommand { CommandText = nameTable, CommandType = CommandType.StoredProcedure }; PropertyInfo[] properties = entity.GetType().GetProperties(); foreach (PropertyInfo property in properties) { Column columna = property.GetCustomAttribute <Column>(); if (columna != null && columna.Exclude) { continue; } string nameColumn = columna == null ? property.Name : columna.Name; object value = property.GetValue(entity, null); if (value is DateTime && ((DateTime)value == DateTime.MinValue || (DateTime)value == DateTime.MaxValue)) { value = null; } if (value is string) { if (string.IsNullOrEmpty((string)value)) { value = null; } } if (value is bool && options.ExcludeBool) { value = null; } if (value is int && (int)value == default(int) && options.ExcludeNumericsDefaults) { value = null; } if (value is long && (long)value == default(long) && options.ExcludeNumericsDefaults) { value = null; } if (value is decimal && (decimal)value == default(decimal) && options.ExcludeNumericsDefaults) { value = null; } if (value is double && Math.Abs((double)value - default(double)) < 0.01 && options.ExcludeNumericsDefaults) { value = null; } if (value != null) { command.Parameters.Add("@" + nameColumn, columna.SqlDataType, GetValue(property.GetValue(entity, null)).ToString().Length).Value = (string)GetValue(property.GetValue(entity, null)); } } return(command); }
public static Statement GetSelect(ISelect entity, OptionsQueryZero options = null) { if (options == null) { options = new OptionsQueryZero(); } Statement statementComplete = new Statement(); if (entity == null) { throw new ZeroException(ZeroCodes.ERR_00_01); } StringBuilder selectFields = new StringBuilder(); StringBuilder selecttWhere = new StringBuilder(); IDictionary <string, object> values = new Dictionary <string, object>(); //obtenemos valores de las anotaciones Table table = entity.GetType().GetCustomAttribute <Table>(); string nameTable = table == null?entity.GetType().Name : table.Name; //se deben obtener todas las propiedades, incluidas las de la super clase PropertyInfo[] properties = entity.GetType().GetProperties(); bool isFirst = true; bool isFirstFilter = true; foreach (PropertyInfo property in properties) { Column columna = property.GetCustomAttribute <Column>(); if (columna != null && columna.Exclude) { continue; } string nameColumn = columna == null ? property.Name : columna.Name; statementComplete.SelectColumns.Add(property.Name, nameColumn); if (isFirst) { isFirst = false; } else { selectFields.Append(", "); } selectFields.Append(nameColumn); object value = property.GetValue(entity, null); bool useEqual = true; if (value is DateTime && ((DateTime)value == DateTime.MinValue || (DateTime)value == DateTime.MaxValue)) { value = null; } if (value is string) { if (string.IsNullOrEmpty((string)value)) { value = null; } if (options.UseLikeForString) { useEqual = false; } } if (value is bool && options.ExcludeBool) { value = null; } if (value is int && (int)value == default(int) && options.ExcludeNumericsDefaults) { value = null; } if (value is long && (long)value == default(long) && options.ExcludeNumericsDefaults) { value = null; } if (value is decimal && (decimal)value == default(decimal) && options.ExcludeNumericsDefaults) { value = null; } if (value is double && Math.Abs((double)value - default(double)) < 0.01 && options.ExcludeNumericsDefaults) { value = null; } if (value != null) { if (isFirstFilter) { isFirstFilter = false; } else { selecttWhere.Append(" and "); } selecttWhere.Append(nameColumn); selecttWhere.Append(useEqual ? " = " : " like "); selecttWhere.Append("@"); selecttWhere.Append(nameColumn); values.Add("@" + nameColumn, GetValue(property.GetValue(entity, null))); } } StringBuilder select = new StringBuilder(); select.Append("Select "); select.Append(selectFields); select.Append(" From "); select.Append(nameTable); if (!isFirstFilter && !options.ExcludeWhere) { select.Append(" Where "); select.Append(selecttWhere); } statementComplete.StatementQuery = select.ToString(); statementComplete.Values = values; if (!string.IsNullOrEmpty(options.WhereComplementary) && !options.ExcludeWhere) { if (options.WhereComplementary.Trim().ToUpper().StartsWith("AND ")) { options.WhereComplementary = options.WhereComplementary.Trim().Substring(3); } if (!isFirstFilter) { //si empieza con and statementComplete.StatementQuery += " and "; } else { statementComplete.StatementQuery += " Where "; } statementComplete.StatementQuery += options.WhereComplementary; } return(statementComplete); }