Beispiel #1
0
        internal static string GetSelectAggregationStatement <T, TColumn>(string aggregateName, Expression <Func <T, TColumn> > projection, Expression <Func <T, bool> > predicate, DialectProvider dialect)
        {
            const string aliasRoot = "r";
            var          tableName = GetTableNameForSql(typeof(T), dialect) + " " + aliasRoot;

            var whereClause = string.Empty;

            if (predicate != null)
            {
                var evaluated = Evaluator.PartialEval(predicate);
                evaluated = LocalCollectionExpander.Rewrite(evaluated);
                var expression = PredicateVisitor.Visit <T>(evaluated, dialect, aliasRoot);
                whereClause = string.Format(SqlWhereFormat, expression);
            }

            var memberExpression  = (MemberExpression)projection.Body;
            var parentPropertyMap = Reflector.GetPropertyMap(typeof(T));

            parentPropertyMap.TryGetValue((PropertyInfo)memberExpression.Member, out var property);
            var columnName = property != null ? property.MappedColumnName : memberExpression.Member.Name;

            var sql = string.Format(SqlSelectAggregateFormat, aggregateName, dialect.IdentifierEscapeStartCharacter + columnName + dialect.IdentifierEscapeEndCharacter, tableName) + whereClause;

            return(sql);
        }
Beispiel #2
0
        public IList <T> GetCachedEntity <T>(DbContext context,
                                             double expirationTimeSeconds,
                                             string cacheKey = null,
                                             Expression <Func <T, bool> > expression = null) where T : class
        {
            var cacheData = new List <T>();

            if (cacheKey == null)
            {
                cacheKey = typeof(T).ToString();
            }

            string expressionKey = null;

            if (expression != null)
            {
                expressionKey = LocalCollectionExpander.Rewrite(Evaluator.PartialEval(expression, QueryResultCache.CanBeEvaluatedLocally)).ToString();
                if (expressionKey.Length > 50)
                {
                    expressionKey = expressionKey.ToMd5Fingerprint();
                }
            }

            try
            {
                if (!_memoryCache.TryGetValue(cacheKey + expressionKey, out cacheData))
                {
                    if (expression != null)
                    {
                        cacheData = context.Set <T>().Where(expression).ToList();
                    }
                    else
                    {
                        cacheData = context.Set <T>().ToList();
                    }

                    if (expirationTimeSeconds > 0)
                    {
                        _memoryCache.Set(cacheKey + expressionKey, cacheData,
                                         new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromSeconds(expirationTimeSeconds)));
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error($"MemoryCaching error {ex.Message}");
            }

            return(cacheData);
        }
        private string CacheKey <T>(Expression <Func <T, bool> > predicate = null, int offset = 0, int limit = 0, Expression <Func <T, object> > orderBy = null, IEnumerable <Expression> paths = null)
        {
            var identity = new StringBuilder();

            if (predicate != null)
            {
                Expression expression = predicate;

                // locally evaluate as much of the query as possible
                expression = Evaluator.PartialEval(expression);

                // support local collections
                expression = LocalCollectionExpander.Rewrite(expression);
                identity.Append(expression);
            }
            else
            {
                identity.Append("All");
            }

            if (offset > 0)
            {
                identity.AppendFormat("|offset:{0}", offset);
            }

            if (limit > 0)
            {
                identity.AppendFormat("|limit:{0}", limit);
            }

            if (orderBy != null)
            {
                identity.AppendFormat("|orderby:{0}", orderBy.ToString());
            }

            if (paths != null)
            {
                var includes = new SortedSet <string>();
                foreach (var path in paths)
                {
                    includes.Add(path.ToString());
                }
                identity.AppendFormat("|includes:[{0}]", string.Join(",", includes));
            }

            var hash = ComputeHash(identity.ToString());

            return(string.Concat(typeof(T).FullName, "/", GetGeneration <T>(), "/", hash));
        }
        // special thanks to Pete Montgomery's post here: http://petemontgomery.wordpress.com/2008/08/07/caching-the-results-of-linq-queries/
        private static string GetHash(Expression expression)
        {
            if (expression == null)
            {
                return(null);
            }

            // locally evaluate as much of the query as possible
            expression = Evaluator.PartialEval(expression);

            // support local collections
            expression = LocalCollectionExpander.Rewrite(expression);

            // use the string representation of the expression for the cache key
            return(expression.ToString());
        }
Beispiel #5
0
        internal static string GetSelectCountStatement <T>(Expression <Func <T, bool> > predicate, DialectProvider dialect)
        {
            const string aliasRoot = "r";
            var          tableName = GetTableNameForSql(typeof(T), dialect) + " " + aliasRoot;

            var whereClause = string.Empty;

            if (predicate != null)
            {
                var evaluated = Evaluator.PartialEval(predicate);
                evaluated = LocalCollectionExpander.Rewrite(evaluated);
                var expression = PredicateVisitor.Visit <T>(evaluated, dialect, aliasRoot);
                whereClause = string.Format(SqlWhereFormat, expression);
            }

            var sql = string.Format(SqlSelectCountFormat, tableName) + whereClause;

            return(sql);
        }
Beispiel #6
0
        private string GetCacheKey <T>(Expression expression, string key) where T : class
        {
            var cacheKey = "";

            if (expression != null)
            {
                cacheKey += LocalCollectionExpander.Rewrite(Evaluator.PartialEval(expression, QueryResultCache.CanBeEvaluatedLocally)).ToString();
            }

            if (!string.IsNullOrEmpty(key))
            {
                cacheKey += key;
            }

            if (cacheKey.Length > 50)
            {
                cacheKey = cacheKey.ToMd5Fingerprint();
            }
            cacheKey += typeof(T).Name + "_iqueryable_";

            return(cacheKey);
        }
        private string CacheKey(Expression <Func <T, bool> > predicate = null, PagedSpecification <T> paging = null)
        {
            var identity = new StringBuilder();

            if (predicate != null)
            {
                Expression expression = predicate;

                // locally evaluate as much of the query as possible
                expression = Evaluator.PartialEval(expression);

                // support local collections
                expression = LocalCollectionExpander.Rewrite(expression);
                identity.Append(expression);
            }
            else
            {
                identity.Append("All");
            }

            if (paging?.PageNumber > 0)
            {
                identity.AppendFormat("|page:{0}", paging.PageNumber);
            }

            if (paging?.PageSize > 0)
            {
                identity.AppendFormat("|size:{0}", paging.PageSize);
            }

            if (paging?.Sorting != null)
            {
                identity.AppendFormat("|orderby:{0}", paging.Sorting);
            }

            var hash = ComputeHash(identity.ToString());

            return(string.Concat(typeof(T).FullName, "/", GetGeneration(), "/", hash));
        }
Beispiel #8
0
        internal static string GetSelectStatement <T, T1, T2, T3, T4>(Expression <Func <T, bool> > predicate, Expression <Func <T, T1, bool> > join1,
                                                                      Expression <Func <T1, T2, bool> > join2, Expression <Func <T2, T3, bool> > join3, Expression <Func <T3, T4, bool> > join4,
                                                                      int page, int pageSize, int skipCount, bool first, DialectProvider dialect, params Sorting <T>[] orderBy)
            where T : class
            where T1 : class
            where T2 : class
            where T3 : class
            where T4 : class
        {
            const string aliasRoot = "r";

            var fake  = typeof(ObjectFactory.Fake);
            var types = new Dictionary <Type, LambdaExpression>();

            if (typeof(T1) != fake && join1 != null)
            {
                types.Add(typeof(T1), join1);
            }
            if (typeof(T2) != fake && join2 != null)
            {
                types.Add(typeof(T2), join2);
            }
            if (typeof(T3) != fake && join3 != null)
            {
                types.Add(typeof(T3), join3);
            }
            if (typeof(T4) != fake && join4 != null)
            {
                types.Add(typeof(T4), join4);
            }

            var mapRoot   = Reflector.GetPropertyNameMap <T>();
            var selection = mapRoot.Values.Where(p => p.IsSelectable && p.IsSimpleType).Select(p => aliasRoot + "." + dialect.IdentifierEscapeStartCharacter + p.MappedColumnName + dialect.IdentifierEscapeEndCharacter).ToDelimitedString(",");

            var tableName = GetTableNameForSql(typeof(T), dialect) + " " + aliasRoot;

            var index         = 1;
            var mapJoinLast   = mapRoot;
            var aliasJoinLast = aliasRoot;

            foreach (var type in types)
            {
                var aliasJoin     = "t" + index;
                var tableNameJoin = GetTableNameForSql(type.Key, dialect) + " " + aliasJoin;
                var mapJoin       = Reflector.GetPropertyNameMap(type.Key);

                var binaryExpression = (BinaryExpression)type.Value.Body;
                var left             = (MemberExpression)binaryExpression.Left;
                var right            = (MemberExpression)binaryExpression.Right;
                var op = GetOperator(binaryExpression.NodeType);

                tableName += string.Format(SqlInnerJoinClauseFormat, tableNameJoin,
                                           aliasJoinLast + "." + dialect.IdentifierEscapeStartCharacter + mapJoinLast[left.Member.Name].MappedColumnName + dialect.IdentifierEscapeEndCharacter, op,
                                           aliasJoin + "." + dialect.IdentifierEscapeStartCharacter + mapJoin[right.Member.Name].MappedColumnName + dialect.IdentifierEscapeEndCharacter);

                mapJoinLast   = mapJoin;
                aliasJoinLast = aliasJoin;

                index++;
            }

            if (types.Count > 0)
            {
                selection = mapJoinLast.Values.Where(p => p.IsSelectable && p.IsSimpleType).Select(p => aliasJoinLast + "." + dialect.IdentifierEscapeStartCharacter + p.MappedColumnName + dialect.IdentifierEscapeEndCharacter).ToDelimitedString(",");
            }

            var sql         = string.Empty;
            var whereClause = string.Empty;

            if (predicate != null)
            {
                var evaluated = Evaluator.PartialEval(predicate);
                evaluated = LocalCollectionExpander.Rewrite(evaluated);
                var expression = PredicateVisitor.Visit <T>(evaluated, dialect, aliasRoot);
                whereClause = string.Format(SqlWhereFormat, expression);
            }

            if (skipCount > 0 || (page > 0 && pageSize > 0))
            {
                if (dialect is SqlServerLegacyDialectProvider)
                {
                    if (orderBy.Length == 0)
                    {
                        var primaryKeyAscending = mapRoot.Keys.Where(p => mapRoot[p].IsPrimaryKey)
                                                  .Select(p => aliasRoot + "." + dialect.IdentifierEscapeStartCharacter + mapRoot[p].MappedColumnName + dialect.IdentifierEscapeEndCharacter + " ASC")
                                                  .ToDelimitedString(",");
                        var primaryKeyDescending = mapRoot.Keys.Where(p => mapRoot[p].IsPrimaryKey)
                                                   .Select(p => aliasRoot + "." + dialect.IdentifierEscapeStartCharacter + mapRoot[p].MappedColumnName + dialect.IdentifierEscapeEndCharacter + " DESC")
                                                   .ToDelimitedString(",");
                        if (page > 0 && pageSize > 0)
                        {
                            sql = string.Format(SqlSelectPagingFormatMssqlLegacy, tableName, selection, primaryKeyAscending, primaryKeyDescending, whereClause, pageSize, page * pageSize);
                        }
                        else
                        {
                            throw new NotSupportedException();
                        }
                    }
                    else
                    {
                        var sort        = new StringBuilder();
                        var sortReverse = new StringBuilder();
                        foreach (var o in orderBy)
                        {
                            var column = aliasRoot + "." + dialect.IdentifierEscapeStartCharacter + mapRoot[((MemberExpression)o.OrderBy.Body).Member.Name].MappedColumnName + dialect.IdentifierEscapeEndCharacter;
                            sort.AppendFormat("{0} {1}, ", column, !o.Reverse ? "ASC" : "DESC");
                            sortReverse.AppendFormat("{0} {1}, ", column, !o.Reverse ? "DESC" : "ASC");
                        }
                        sort.Length        -= 2;
                        sortReverse.Length -= 2;
                        if (page > 0 && pageSize > 0)
                        {
                            sql = string.Format(SqlSelectPagingFormatMssqlLegacy, tableName, selection, sort, sortReverse, whereClause, pageSize, page * pageSize);
                        }
                        else
                        {
                            throw new NotSupportedException();
                        }
                    }
                }
                else if (dialect is SqlServerDialectProvider || dialect is OracleDialectProvider)
                {
                    var selectionWithoutAlias =
                        mapRoot.Values.Where(p => p.IsSelectable && p.IsSimpleType).Select(p => dialect.IdentifierEscapeStartCharacter + p.MappedColumnName + dialect.IdentifierEscapeEndCharacter).ToDelimitedString(",");

                    if (orderBy.Length == 0)
                    {
                        var primaryKey =
                            mapRoot.Keys.Where(p => mapRoot[p].IsPrimaryKey)
                            .Select(p => aliasRoot + "." + dialect.IdentifierEscapeStartCharacter + mapRoot[p].MappedColumnName + dialect.IdentifierEscapeEndCharacter)
                            .ToDelimitedString(",");
                        if (page > 0 && pageSize > 0)
                        {
                            sql = string.Format(SqlSelectPagingFormatRowNumber, tableName, selection, primaryKey, whereClause, (page - 1) * pageSize, page * pageSize, selectionWithoutAlias);
                        }
                        else
                        {
                            sql = string.Format(SqlSelectSkipFormatRowNumber, tableName, selection, primaryKey, whereClause, skipCount, selectionWithoutAlias);
                        }
                    }
                    else
                    {
                        var sort = new StringBuilder();
                        foreach (var o in orderBy)
                        {
                            var column = aliasRoot + "." + dialect.IdentifierEscapeStartCharacter + mapRoot[((MemberExpression)o.OrderBy.Body).Member.Name].MappedColumnName + dialect.IdentifierEscapeEndCharacter;
                            sort.AppendFormat("{0} {1}, ", column, !o.Reverse ? "ASC" : "DESC");
                        }
                        sort.Length -= 2;
                        if (page > 0 && pageSize > 0)
                        {
                            sql = string.Format(SqlSelectPagingFormatRowNumber, tableName, selection, sort, whereClause, (page - 1) * pageSize, page * pageSize, selectionWithoutAlias);
                        }
                        else
                        {
                            sql = string.Format(SqlSelectSkipFormatRowNumber, tableName, selection, sort, whereClause, skipCount, selectionWithoutAlias);
                        }
                    }
                }
                else if (dialect is SqlServerLatestDialectProvider)
                {
                    if (orderBy.Length == 0)
                    {
                        var primaryKey =
                            mapRoot.Keys.Where(p => mapRoot[p].IsPrimaryKey)
                            .Select(p => aliasRoot + "." + dialect.IdentifierEscapeStartCharacter + mapRoot[p].MappedColumnName + dialect.IdentifierEscapeEndCharacter)
                            .ToDelimitedString(",");
                        if (page > 0 && pageSize > 0)
                        {
                            sql = string.Format(SqlSelectPagingWithOrderByFormat, tableName, selection, whereClause, primaryKey, whereClause, (page - 1) * pageSize, pageSize);
                        }
                        else
                        {
                            sql = string.Format(SqlSelectSkipWithOrderByFormat, tableName, selection, whereClause, primaryKey, skipCount);
                        }
                    }
                    else
                    {
                        var sort = new StringBuilder();
                        foreach (var o in orderBy)
                        {
                            var column = aliasRoot + "." + dialect.IdentifierEscapeStartCharacter + mapRoot[((MemberExpression)o.OrderBy.Body).Member.Name].MappedColumnName + dialect.IdentifierEscapeEndCharacter;
                            sort.AppendFormat("{0} {1}, ", column, !o.Reverse ? "ASC" : "DESC");
                        }
                        sort.Length -= 2;
                        if (page > 0 && pageSize > 0)
                        {
                            sql = string.Format(SqlSelectPagingWithOrderByFormat, tableName, selection, whereClause, sort, (page - 1) * pageSize, pageSize);
                        }
                        else
                        {
                            sql = string.Format(SqlSelectSkipWithOrderByFormat, tableName, selection, whereClause, sort, skipCount);
                        }
                    }
                }
                else
                {
                    var orderByClause = "";
                    if (orderBy.Length > 0)
                    {
                        var sort = new StringBuilder(" ORDER BY ");
                        foreach (var o in orderBy)
                        {
                            var column = aliasRoot + "." + dialect.IdentifierEscapeStartCharacter + mapRoot[((MemberExpression)o.OrderBy.Body).Member.Name].MappedColumnName + dialect.IdentifierEscapeEndCharacter;
                            sort.AppendFormat("{0} {1}, ", column, !o.Reverse ? "ASC" : "DESC");
                        }
                        sort.Length  -= 2;
                        orderByClause = sort.ToString();
                    }
                    if (page > 0 && pageSize > 0)
                    {
                        sql = string.Format(SqlSelectPagingFormat, tableName, selection, whereClause, orderByClause, pageSize, (page - 1) * pageSize);
                    }
                    else
                    {
                        sql = string.Format(SqlSelectSkipFormat, tableName, selection, whereClause, orderByClause, skipCount);
                    }
                }
            }
            else
            {
                sql = string.Format(SqlSelectFormat, tableName, selection) + whereClause;
                if (orderBy.Length > 0)
                {
                    var sort = new StringBuilder(" ORDER BY ");
                    foreach (var o in orderBy)
                    {
                        var column = aliasRoot + "." + dialect.IdentifierEscapeStartCharacter + mapRoot[((MemberExpression)o.OrderBy.Body).Member.Name].MappedColumnName + dialect.IdentifierEscapeEndCharacter;
                        sort.AppendFormat("{0} {1}, ", column, !o.Reverse ? "ASC" : "DESC");
                    }
                    sort.Length -= 2;
                    sql         += sort;
                }
            }

            if (first)
            {
                if (dialect is SqlServerDialectProvider)
                {
                    sql = string.Format(SqlSelectFirstFormatMssql, sql);
                }
                else if (dialect is OracleDialectProvider)
                {
                    sql = string.Format(SqlSelectFirstFormatOracle, sql);
                }
                else
                {
                    sql = string.Format(SqlSelectFirstFormat, sql);
                }
            }

            return(sql);
        }
Beispiel #9
0
        public long Delete <T>(params Expression <Func <T, bool> >[] criteria) where T : class
        {
            var connection        = DbContext.Database.Connection;
            var destroyConnection = false;
            var count             = 0L;

            try
            {
                using (var scope = new TransactionScope(TransactionScopeOption.Required))
                {
                    if (connection.State != ConnectionState.Open)
                    {
                        connection.Open();
                        destroyConnection = true;
                    }

                    using (var command = connection.CreateCommand())
                    {
                        var regexWhere    = new Regex(@"(?<=WHERE\s+)(?<criteria>.*)");
                        var regexAsClause = new Regex(@"(?<=FROM\s+.*?AS\s+)(?<as>.*?)(?=(\s+|$))");

                        var builder  = new StringBuilder();
                        var notFirst = false;

                        foreach (var criterion in criteria)
                        {
                            if (notFirst)
                            {
                                builder.Append(";");
                                builder.AppendLine();
                            }

                            Expression expression = criterion;
                            expression = Evaluator.PartialEval(expression);
                            expression = LocalCollectionExpander.Rewrite(expression);

                            var sql = All <T>().Where((Expression <Func <T, bool> >)expression).ToString();

                            var matchWhere    = regexWhere.Match(sql);
                            var matchAsClause = regexAsClause.Match(sql);

                            var asClause    = matchAsClause.Groups["as"].Value.Trim();
                            var whereClause = matchWhere.Groups["criteria"].Value;
                            whereClause = whereClause.Replace(asClause + ".", "");

                            var notFirstType = false;
                            foreach (var type in GetTypeHierarchy(typeof(T)))
                            {
                                var tableName = DbContext.GetTableName(type);
                                if (string.IsNullOrEmpty(tableName))
                                {
                                    break;
                                }

                                if (notFirstType)
                                {
                                    builder.Append(";");
                                    builder.AppendLine();
                                }

                                builder.Append("DELETE FROM ");
                                builder.Append(tableName);
                                builder.AppendLine();
                                builder.Append("WHERE ");
                                builder.Append(whereClause);
                                notFirstType = true;
                            }

                            if (notFirstType)
                            {
                                notFirst = true;
                            }
                        }

                        command.CommandTimeout = 0;
                        command.CommandText    = builder.ToString();
                        count = command.ExecuteNonQuery();

                        scope.Complete();
                    }
                }
            }
            finally
            {
                if (destroyConnection)
                {
                    connection.Close();
                }
            }
            return(count);
        }
Beispiel #10
0
        public long Update <T>(params BulkUpdateOperation <T>[] bulkOperations) where T : class
        {
            var connection        = DbContext.Database.Connection;
            var destroyConnection = false;
            var count             = 0L;

            try
            {
                using (var scope = new TransactionScope(TransactionScopeOption.Required))
                {
                    if (connection.State != ConnectionState.Open)
                    {
                        connection.Open();
                        destroyConnection = true;
                    }

                    using (var command = connection.CreateCommand())
                    {
                        Dictionary <string, string> mappings = null;

                        var regexWhere    = new Regex(@"(?<=WHERE\s+)(?<criteria>.*)");
                        var regexAsClause = new Regex(@"(?<=FROM\s+.*?AS\s+)(?<as>.*?)(?=(\s+|$))");

                        var builder  = new StringBuilder();
                        var notFirst = false;

                        foreach (var bulkOperation in bulkOperations)
                        {
                            if (notFirst)
                            {
                                builder.Append(";");
                                builder.AppendLine();
                            }

                            Expression criteriaExpression = bulkOperation.Criteria;
                            criteriaExpression = Evaluator.PartialEval(criteriaExpression);
                            criteriaExpression = LocalCollectionExpander.Rewrite(criteriaExpression);

                            var sql = All <T>().Where((Expression <Func <T, bool> >)criteriaExpression).ToString();

                            if (mappings == null)
                            {
                                mappings = ExtractColumnMappings(typeof(T), DbContext);
                            }

                            var matchWhere    = regexWhere.Match(sql);
                            var matchAsClause = regexAsClause.Match(sql);

                            var asClause    = matchAsClause.Groups["as"].Value.Trim();
                            var whereClause = matchWhere.Groups["criteria"].Value;
                            whereClause = whereClause.Replace(asClause + ".", "");

                            var updateBody = (MemberInitExpression)bulkOperation.Update.Body;

                            var i = 0;
                            var notFirstColumn = false;
                            foreach (var binding in updateBody.Bindings)
                            {
                                if (notFirstColumn)
                                {
                                    builder.AppendLine(", ");
                                }

                                var    name = binding.Member.Name;
                                string columnName;
                                if (!mappings.TryGetValue(name, out columnName))
                                {
                                    continue;
                                }

                                if (!notFirstColumn)
                                {
                                    builder.Append("UPDATE [");
                                    builder.Append(DbContext.GetTableName <T>());
                                    builder.AppendLine("]");
                                    builder.Append("SET ");
                                }

                                object value;
                                var    memberExpression = ((MemberAssignment)binding).Expression;

                                var selfReference    = false;
                                var isLeft           = false;
                                var binaryExpression = memberExpression as BinaryExpression;
                                if (binaryExpression != null)
                                {
                                    if (binaryExpression.Left is MemberExpression && ((MemberExpression)binaryExpression.Left).Member.Name == name)
                                    {
                                        isLeft           = true;
                                        selfReference    = true;
                                        memberExpression = binaryExpression.Right;
                                    }
                                    else if (binaryExpression.Right is MemberExpression && ((MemberExpression)binaryExpression.Right).Member.Name == name)
                                    {
                                        selfReference    = true;
                                        memberExpression = binaryExpression.Left;
                                    }
                                }

                                var constantExpression = memberExpression as ConstantExpression;
                                if (constantExpression != null)
                                {
                                    value = constantExpression.Value;
                                }
                                else
                                {
                                    var lambda = Expression.Lambda(memberExpression, null);
                                    value = lambda.Compile().DynamicInvoke();
                                }

                                if (value == null)
                                {
                                    builder.AppendFormat("[{0}] = NULL", columnName);
                                }
                                else
                                {
                                    var type      = value.GetType();
                                    var isComplex = type.IsClass && !(value is IEnumerable);
                                    if (isComplex)
                                    {
                                        var primaryKey = MetaDataProvider.Current.GetPrimaryKeyValue(value, DbContext);
                                        var j          = 0;
                                        foreach (var pair in columnName.Split('|').Zip(primaryKey, Tuple.Create))
                                        {
                                            builder.AppendFormat("{0} = @{1}", pair.Item1, "p" + i + "_" + j);

                                            var parameter = command.CreateParameter();
                                            parameter.ParameterName = "p" + i + "_" + j;
                                            parameter.Value         = pair.Item2;
                                            command.Parameters.Add(parameter);

                                            j++;
                                        }
                                    }
                                    else if (selfReference)
                                    {
                                        switch (binaryExpression.NodeType)
                                        {
                                        case ExpressionType.Add:
                                        {
                                            if (value is string)
                                            {
                                                var providerName = DbFactory.GetProviderInvariantNameByConnectionString(connection.ConnectionString, null);
                                                if (providerName.Contains("SqlClient"))
                                                {
                                                    builder.AppendFormat(isLeft ? "[{0}] = [{0}] + @{1}" : "[{0}] = @{1} + [{0}]", columnName, "p" + i);
                                                }
                                                else if (providerName.Contains("MySql"))
                                                {
                                                    builder.AppendFormat(isLeft ? "[{0}] = CONCAT([{0}], @{1})" : "[{0}] = CONCAT(@{1}, [{0}])", columnName, "p" + i);
                                                }
                                                else
                                                {
                                                    builder.AppendFormat(isLeft ? "[{0}] = [{0}] || @{1}" : "[{0}] = @{1} || [{0}]", columnName, "p" + i);
                                                }
                                            }
                                            else
                                            {
                                                builder.AppendFormat("[{0}] = [{0}] + @{1}", columnName, "p" + i);
                                            }
                                            break;
                                        }

                                        case ExpressionType.Subtract:
                                        {
                                            builder.AppendFormat(isLeft ? "[{0}] = [{0}] - @{1}" : "[{0}] = @{1} - [{0}]", columnName, "p" + i);
                                            break;
                                        }

                                        case ExpressionType.Multiply:
                                        {
                                            builder.AppendFormat("[{0}] = [{0}] * @{1}", columnName, "p" + i);
                                            break;
                                        }

                                        case ExpressionType.Divide:
                                        {
                                            builder.AppendFormat(isLeft ? "[{0}] = [{0}] / @{1}" : "[{0}] = @{1} / [{0}]", columnName, "p" + i);
                                            break;
                                        }

                                        default:
                                        {
                                            builder.AppendFormat("[{0}] = @{1}", columnName, "p" + i);
                                            break;
                                        }
                                        }
                                    }
                                    else
                                    {
                                        builder.AppendFormat("[{0}] = @{1}", columnName, "p" + i);
                                    }

                                    if (!isComplex)
                                    {
                                        var parameter = command.CreateParameter();
                                        parameter.ParameterName = "p" + i;
                                        parameter.Value         = value;
                                        command.Parameters.Add(parameter);
                                    }

                                    i++;
                                }
                                notFirstColumn = true;
                            }

                            if (i == 0)
                            {
                                continue;
                            }

                            builder.AppendLine();
                            builder.Append("WHERE ");
                            builder.Append(whereClause);
                            notFirst = true;
                        }

                        command.CommandTimeout = 0;
                        command.CommandText    = builder.ToString();

                        if (command.CommandText.Length > 0)
                        {
                            count = command.ExecuteNonQuery();
                        }

                        scope.Complete();
                    }
                }
            }
            finally
            {
                if (destroyConnection)
                {
                    connection.Close();
                }
            }
            return(count);
        }
Beispiel #11
0
            public IEnumerable <T> FindAll(Expression <Func <T, bool> > criteria, int offset = 0, int limit = 0, Sorting <T> sorting = null)
            {
                _repository.SetConfiguration(typeof(T));

                var typeCount = _types.Sum(t => t.Item1.Length);

                if (typeCount == 0)
                {
                    return(Enumerable.Empty <T>().AsQueryable());
                }

                if (typeCount == 1)
                {
                    return(_repository.FindAll(criteria, offset, limit, sorting));
                }

                if (_repository._options.UseStoredProcedures)
                {
                    var parameters          = new List <Param>();
                    var evaluatedExpression = (Expression <Func <T, bool> >)LocalCollectionExpander.Rewrite(Evaluator.PartialEval(criteria));

                    var map = Reflector.GetPropertyNameMap(typeof(T));
                    WalkTree((BinaryExpression)evaluatedExpression.Body, ExpressionType.Default, ref parameters, map);

                    if (offset >= 0 && limit > 0)
                    {
                        parameters.Add(new Param {
                            Name = "offset", Value = offset, DbType = DbType.Int32
                        });
                        parameters.Add(new Param {
                            Name = "limit", Value = limit, DbType = DbType.Int32
                        });
                    }

                    if (sorting != null && sorting.OrderBy != null)
                    {
                        var memberExpression = sorting.OrderBy.Body as MemberExpression;
                        if (memberExpression != null)
                        {
                            parameters.Add(new Param {
                                Name = "orderBy", Value = map[memberExpression.Member.Name].MappedColumnName
                            });
                        }
                    }

                    var request = new OperationRequest {
                        Operation = "FindAll", OperationType = OperationType.StoredProcedure, Types = _types.Select(t => t.Item1).Flatten().Distinct().ToArray(), Parameters = parameters, Connection = _repository.Connection
                    };
                    var response = ObjectFactory.Execute <T>(request);
                    var result   = ObjectFactory.Translate <T>(response);
                    if (request.Types.Count > 1)
                    {
                        result = ((IMultiResult)result).Aggregate <T>();
                    }
                    return(result);
                }
                else
                {
                    var result = sorting != null
                        ? ObjectFactory.Select(criteria, page : limit > 0?offset / limit + 1 : 0, pageSize : limit, skipCount : offset, connection : _repository.Connection, orderBy : sorting.ToArray().Select(s => new Nemo.Sorting <T> {
                        OrderBy = s.OrderBy, Reverse = s.Reverse
                    }).ToArray())
                        : ObjectFactory.Select(criteria, page: limit > 0 ? offset / limit + 1 : 0, pageSize: limit, skipCount: offset, connection: _repository.Connection);

                    foreach (var types in _types)
                    {
                        MethodInfo method = null;
                        switch (types.Item1.Length)
                        {
                        case 2:
                            method = IncludeMethod2;
                            break;

                        case 3:
                            method = IncludeMethod3;
                            break;

                        case 4:
                            method = IncludeMethod4;
                            break;

                        case 5:
                            method = IncludeMethod5;
                            break;
                        }

                        if (method != null)
                        {
                            result = (IEnumerable <T>)method.MakeGenericMethod(types.Item1.ToArray()).Invoke(null, new object[] { result }.Concat(types.Item2).ToArray());
                        }
                    }

                    return(result);
                }
            }
Beispiel #12
0
            public IEnumerable <T> FindAll(Expression <Func <T, bool> > criteria, int offset = 0, int limit = 0, Expression <Func <T, object> > orderBy = null)
            {
                var typeCount = _types.Sum(t => t.Item1.Length);

                if (typeCount == 0)
                {
                    return(Enumerable.Empty <T>().AsQueryable());
                }

                if (typeCount == 1)
                {
                    return(_repository.FindAll(criteria, offset, limit, orderBy));
                }

                if (_repository._useStoredProcedures)
                {
                    var parameters          = new List <Param>();
                    var evaluatedExpression = (Expression <Func <T, bool> >)LocalCollectionExpander.Rewrite(Evaluator.PartialEval(criteria));

                    var map = Reflector.GetPropertyNameMap(typeof(T));
                    WalkTree((BinaryExpression)evaluatedExpression.Body, ExpressionType.Default, ref parameters, map);

                    if (offset >= 0 && limit > 0)
                    {
                        parameters.Add(new Param {
                            Name = "offset", Value = offset, DbType = DbType.Int32
                        });
                        parameters.Add(new Param {
                            Name = "limit", Value = limit, DbType = DbType.Int32
                        });
                    }

                    if (orderBy != null)
                    {
                        var memberExpression = orderBy.Body as MemberExpression;
                        if (memberExpression != null)
                        {
                            parameters.Add(new Param {
                                Name = "orderBy", Value = map[memberExpression.Member.Name].MappedColumnName
                            });
                        }
                    }

                    var response = ObjectFactory.Execute <T>(new OperationRequest {
                        Operation = "FindAll", OperationType = OperationType.StoredProcedure, Types = _types.Select(t => t.Item1).Flatten().Distinct().ToArray(), Parameters = parameters
                    });
                    return(ObjectFactory.Translate <T>(response));
                }
                else
                {
                    var result = ObjectFactory.Select(criteria, page: limit > 0 ? offset / limit + 1 : 0, pageSize: limit, orderBy: new[] { Tuple.Create(orderBy, SortingOrder.Ascending) });

                    foreach (var types in _types)
                    {
                        MethodInfo method = null;
                        switch (types.Item1.Length)
                        {
                        case 2:
                            method = _includeMethod2;
                            break;

                        case 3:
                            method = _includeMethod3;
                            break;

                        case 4:
                            method = _includeMethod4;
                            break;

                        case 5:
                            method = _includeMethod5;
                            break;
                        }

                        if (method != null)
                        {
                            result = (IEnumerable <T>)method.MakeGenericMethod(types.Item1.ToArray()).Invoke(null, new object[] { result }.Concat(types.Item2).ToArray());
                        }
                    }

                    return(result);
                }
            }