protected override SqlProvider VisitFreeText(FreeTextProvider provider) { SqlFreeTextTable fromTable; QueryParameterBinding[] bindings; var stringTypeMapping = Driver.GetTypeMapping(StringType); var criteriaBinding = new QueryParameterBinding( stringTypeMapping, provider.SearchCriteria.Invoke, QueryParameterBindingType.Regular); var index = provider.PrimaryIndex.Resolve(Handlers.Domain.Model); var table = Mapping[index.ReflectedType]; var columns = provider.Header.Columns.Select(column => column.Name).ToList(); if (provider.TopN == null) { fromTable = SqlDml.FreeTextTable(table, criteriaBinding.ParameterReference, columns); bindings = new[] { criteriaBinding }; } else { var intTypeMapping = Driver.GetTypeMapping(Int32Type); var topNBinding = new QueryParameterBinding(intTypeMapping, context => provider.TopN.Invoke(context), QueryParameterBindingType.Regular); fromTable = SqlDml.FreeTextTable(table, criteriaBinding.ParameterReference, columns, topNBinding.ParameterReference); bindings = new[] { criteriaBinding, topNBinding }; } var fromTableRef = SqlDml.QueryRef(fromTable); var select = SqlDml.Select(fromTableRef); select.Columns.Add(fromTableRef.Columns[0]); select.Columns.Add(SqlDml.Cast(fromTableRef.Columns[1], SqlType.Double), "RANK"); return(CreateProvider(select, bindings, provider)); }
protected override SqlProvider VisitFreeText(FreeTextProvider provider) { var rankColumnName = provider.Header.Columns.Last().Name; var stringTypeMapping = Driver.GetTypeMapping(typeof(string)); var binding = new QueryParameterBinding(stringTypeMapping, provider.SearchCriteria.Invoke, QueryParameterBindingType.Regular); SqlSelect select = SqlDml.Select(); var realPrimaryIndex = provider.PrimaryIndex.Resolve(Handlers.Domain.Model); var index = realPrimaryIndex.ReflectedType.Indexes.PrimaryIndex; var query = BuildProviderQuery(index); var table = Mapping[realPrimaryIndex.ReflectedType]; var fromTable = SqlDml.FreeTextTable(table, binding.ParameterReference, table.Columns.Select(column => column.Name).AddOne(rankColumnName).ToList()); var fromTableRef = SqlDml.QueryRef(fromTable); foreach (var column in query.Columns) { select.Columns.Add(fromTableRef.Columns[column.Name] ?? column); } select.Columns.Add(SqlDml.Cast(fromTableRef.Columns[rankColumnName], SqlType.Double), rankColumnName); select.From = fromTableRef; if (provider.TopN != null) { select.Limit = provider.TopN.Invoke(); select.OrderBy.Add(select.Columns[rankColumnName], false); } return(CreateProvider(select, binding, provider)); }
private void AddConstantValue(AddValueContext addContext) { SqlTableColumn column = SqlDml.TableColumn(addContext.Statement.Table, addContext.Field.Column.Name); SqlExpression value; object constant = Expression.Lambda(addContext.Lambda.Body, null).Compile().DynamicInvoke(); if (constant == null) { value = SqlDml.Null; } else { QueryParameterBinding binding = parent.QueryBuilder.CreateParameterBinding(constant.GetType(), () => constant); parent.Bindings.Add(binding); value = binding.ParameterReference; } addContext.Statement.AddValue(column, value); }
protected override SqlProvider VisitFreeText(FreeTextProvider provider) { var rankColumnName = provider.Header.Columns[provider.Header.Columns.Count - 1].Name; var stringTypeMapping = Driver.GetTypeMapping(WellKnownTypes.StringType); var binding = new QueryParameterBinding(stringTypeMapping, provider.SearchCriteria.Invoke, QueryParameterBindingType.Regular); var select = SqlDml.Select(); var realPrimaryIndex = provider.PrimaryIndex.Resolve(Handlers.Domain.Model); var index = realPrimaryIndex.ReflectedType.Indexes.PrimaryIndex; var query = BuildProviderQuery(index); var table = Mapping[realPrimaryIndex.ReflectedType]; var fromTable = SqlDml.FreeTextTable(table, binding.ParameterReference, table.Columns.Select(column => column.Name).Append(rankColumnName).ToArray(table.Columns.Count + 1)); var fromTableRef = SqlDml.QueryRef(fromTable); foreach (var column in query.Columns) { select.Columns.Add(fromTableRef.Columns[column.Name] ?? column); } select.Columns.Add(SqlDml.Cast(fromTableRef.Columns[rankColumnName], SqlType.Double), rankColumnName); select.From = fromTableRef; if (provider.TopN == null) { return(CreateProvider(select, binding, provider)); } var intTypeMapping = Driver.GetTypeMapping(typeof(int)); var topNBinding = new QueryParameterBinding( intTypeMapping, context => provider.TopN.Invoke(context), QueryParameterBindingType.Regular); select.Limit = topNBinding.ParameterReference; select.OrderBy.Add(select.Columns[rankColumnName], false); return(CreateProvider(select, new[] { binding, topNBinding }, provider)); }
private void AddEntityValue(AddValueContext addContext) { if (addContext.EntityParamExists) { throw new NotSupportedException("Expressions with reference to updating entity are not supported"); } var methodCall = addContext.Descriptor.Expression as MethodCallExpression; int i; if (methodCall != null) { if (methodCall.Method.DeclaringType == typeof(QueryEndpoint) && methodCall.Method.Name.In("Single", "SingleOrDefault")) { object[] keys; if (methodCall.Arguments[0].Type == typeof(Key) || methodCall.Arguments[0].Type.IsSubclassOf(typeof(Key))) { var key = (Key)methodCall.Arguments[0].Invoke(); keys = new object[key.Value.Count]; for (i = 0; i < keys.Length; i++) { keys[i] = key.Value.GetValue(i); } } else { keys = (object[])methodCall.Arguments[0].Invoke(); } i = -1; foreach (ColumnInfo column in addContext.Field.Columns) { i++; SqlExpression value; if (keys[i] == null) { value = SqlDml.Null; } else { object v = keys[i]; QueryParameterBinding binding = parent.QueryBuilder.CreateParameterBinding(v.GetType(), () => v); parent.Bindings.Add(binding); value = binding.ParameterReference; } SqlTableColumn c = SqlDml.TableColumn(addContext.Statement.Table, column.Name); addContext.Statement.AddValue(c, value); } return; } if (methodCall.Method.DeclaringType == typeof(Queryable) && methodCall.Method.Name.In("Single", "SingleOrDefault", "First", "FirstOrDefault")) { Expression exp = methodCall.Arguments[0]; TypeInfo info = parent.GetTypeInfo(addContext.Field.ValueType); if (methodCall.Arguments.Count == 2) { exp = Expression.Call( typeof(Queryable), "Where", new[] { info.UnderlyingType }, exp, methodCall.Arguments[1]); } exp = Expression.Call(typeof(Queryable), "Take", new[] { info.UnderlyingType }, exp, Expression.Constant(1)); i = -1; foreach (FieldInfo field in info.Key.Fields) { i++; ParameterExpression p = Expression.Parameter(info.UnderlyingType); LambdaExpression lambda = Expression.Lambda( typeof(Func <,>).MakeGenericType(info.UnderlyingType, field.ValueType), Expression.MakeMemberAccess(p, field.UnderlyingProperty), p); IQueryable q = ((IQueryProvider)parent.QueryProvider).CreateQuery( Expression.Call(typeof(Queryable), "Select", new[] { info.UnderlyingType, field.ValueType }, exp, lambda)); QueryTranslationResult request = parent.GetRequest(field.ValueType, q); parent.Bindings.AddRange(request.ParameterBindings); SqlTableColumn c = SqlDml.TableColumn(addContext.Statement.Table, addContext.Field.Columns[i].Name); addContext.Statement.AddValue(c, SqlDml.SubQuery((ISqlQueryExpression)request.Query)); } return; } } i = -1; var entity = (IEntity)Expression.Lambda(addContext.Lambda.Body, null).Compile().DynamicInvoke(); foreach (ColumnInfo column in addContext.Field.Columns) { i++; SqlExpression value; if (entity == null) { value = SqlDml.Null; } else { object v = entity.Key.Value.GetValue(i); QueryParameterBinding binding = parent.QueryBuilder.CreateParameterBinding(v.GetType(), () => v); parent.Bindings.Add(binding); value = binding.ParameterReference; } SqlTableColumn c = SqlDml.TableColumn(addContext.Statement.Table, column.Name); addContext.Statement.AddValue(c, value); } }