public void Accessor_Guard_String() { Assert.Equal( $"IIF(((t == null) OrElse (t.String == null)), null, {Compat.ExpectedConvert("t.String.Length", "Nullable`1")})", CompileAccessor(true, "String.Length") ); }
public void GroupingAddedToSorting() { var loadOptions = new SampleLoadOptions { Sort = new[] { new SortingInfo { Selector = "Item2" }, new SortingInfo { Selector = "Item3" } }, Group = new[] { new GroupingInfo { Selector = "Item1" }, new GroupingInfo { Selector = "Item2", Desc = true } // this must win }, GuardNulls = false }; string BuildLoadExpr() => Compat.CreateDataSourceExpressionBuilder <Tuple <int, int, int> >(loadOptions).BuildLoadExpr().ToString(); Assert.Equal( "data.OrderBy(obj => obj.Item1).ThenByDescending(obj => obj.Item2).ThenBy(obj => obj.Item3)", BuildLoadExpr() ); loadOptions.Sort = null; Assert.Contains("OrderBy", BuildLoadExpr()); }
public void BuildGroupCountExpr() { string BuildExpr(DataSourceLoadOptionsBase options) => Compat.CreateDataSourceExpressionBuilder <Tuple <int, int> >(options) .BuildGroupCountExpr() .ToString(); var error = Record.Exception(delegate { BuildExpr(new SampleLoadOptions { Group = new[] { new GroupingInfo { Selector = "Item1" }, new GroupingInfo { Selector = "Item2" } } }); }); Assert.True(error is InvalidOperationException); Assert.Equal( "data.Where(obj => (obj.Item2 == 1)).Select(obj => obj.Item1).Distinct().Count()", BuildExpr(new SampleLoadOptions { GuardNulls = false, Filter = new[] { "Item2", "1" }, Group = new[] { new GroupingInfo { Selector = "Item1" } } }) ); }
public void GroupInterval_Numeric() { string Compile <T>(string selector, bool guardNulls) { var compiler = new RemoteGroupExpressionCompiler <T>( guardNulls, new[] { new GroupingInfo { Selector = selector, GroupInterval = "123" } }, null, null ); return(compiler.Compile(CreateTargetParam <T>()).ToString()); } Assert.Contains("I0 = (obj - (obj % 123)", Compile <double>("this", false)); Assert.Contains("I0 = (obj - (obj % 123)", Compile <double?>("this", false)); Assert.Contains( $"I0 = IIF(((obj == null) OrElse (obj.Item1 == null)), null, {Compat.ExpectedConvert("(obj.Item1.Length - (obj.Item1.Length % 123))", "Nullable`1")})", Compile <Tuple <string> >("Item1.Length", true) ); }
public void Accessor_Guard_NullInStruct() { Assert.Equal( $"IIF(((t == null) OrElse (t.StructWithRef.Ref == null)), null, {Compat.ExpectedConvert("t.StructWithRef.Ref.Value", "Nullable`1")})", CompileAccessor(true, "StructWithRef.Ref.Value") ); }
public void DefaultSortAndPrimaryKey() { var options = new SampleLoadOptions { PrimaryKey = new[] { "Item1" }, DefaultSort = "Item1", Sort = new[] { new SortingInfo { Selector = "Item1" } }, GuardNulls = false }; { var builder = Compat.CreateDataSourceExpressionBuilder <Tuple <int, int, int> >(options); Assert.Equal( "data.OrderBy(obj => obj.Item1)", builder.BuildLoadExpr().ToString() ); } options.DefaultSort = "Item2"; options.Sort[0].Selector = "Item3"; { var builder = Compat.CreateDataSourceExpressionBuilder <Tuple <int, int, int> >(options); Assert.Equal( "data.OrderBy(obj => obj.Item3).ThenBy(obj => obj.Item2).ThenBy(obj => obj.Item1)", builder.BuildLoadExpr().ToString() ); } }
public void SortByPrimaryKey() { void Case(Action <DataSourceLoadOptionsBase> initOptions, Action <string> assert) { var source = new[] { new { ID = 1, Value = "A" } }; var loadOptions = new SampleLoadOptions { GuardNulls = false, PrimaryKey = new[] { "ID" }, SortByPrimaryKey = false }; initOptions?.Invoke(loadOptions); assert(Compat.CreateDataSourceExpressionBuilder(source.AsQueryable(), loadOptions).BuildLoadExpr().ToString()); } Case( null, expr => Assert.DoesNotContain("OrderBy", expr) ); Case( options => options.DefaultSort = "Value", expr => { Assert.Contains(".OrderBy(obj => obj.Value)", expr); Assert.DoesNotContain("ThenBy", expr); } ); }
public void Accessor_Guard_Nullable() { Assert.Equal("IIF((t == null), null, t.Nullable)", CompileAccessor(true, "Nullable")); Assert.Equal( $"IIF(((t == null) OrElse (t.Nullable == null)), null, {Compat.ExpectedConvert("t.Nullable.Value.Year", "Nullable`1")})", CompileAccessor(true, "Nullable.Year") ); }
public void Build_Filter() { var builder = Compat.CreateDataSourceExpressionBuilder <int>(new SampleLoadOptions { Filter = new object[] { "this", ">", 123 } }); var expr = builder.BuildLoadExpr(); Assert.Equal("data.Where(obj => (obj > 123))", expr.ToString()); }
public void Build_FilterAsEmptyList() { // To mitigate cases like https://devexpress.com/issue=T483154 var builder = Compat.CreateDataSourceExpressionBuilder <int>(new SampleLoadOptions { Filter = new object[0] }); Assert.DoesNotContain(".Where", builder.BuildLoadExpr().ToString()); }
public void Build_SkipTake() { var builder = Compat.CreateDataSourceExpressionBuilder <int>(new SampleLoadOptions { Skip = 111, Take = 222 }); var expr = builder.BuildLoadExpr(); Assert.Equal("data.Skip(111).Take(222)", expr.ToString()); }
public static void Run <T>(IQueryable <T> data) where T : IEntity { if (Compat.CanUseRemoteAvg(data.Provider)) { RunCore(data, new[] { "count", "min", "max", "sum", "avg" }); } else { RunCore(data, new[] { "count", "min", "max", "sum" }); RunCore(data, new[] { "avg" }); } }
public static void Run <T>(IQueryable <T> data) where T : IEntity { var loadOptions = new SampleLoadOptions { RemoteGrouping = true, Group = BuildGroupParams(), GroupSummary = BuildSummaryParams(Compat.CanUseRemoteAvg(data.Provider)) }; Assert.Null(Record.Exception(delegate { DataSourceLoader.Load(data, loadOptions); })); }
public void RemoteSelectFalse() { var options = new SampleLoadOptions { Select = new[] { "abc" }, RemoteSelect = false }; Assert.Equal( "data", Compat.CreateDataSourceExpressionBuilder <object>(options, false).BuildLoadExpr().ToString() ); }
public void AlwaysOrderDataByPrimaryKey() { var options = new SampleLoadOptions { PrimaryKey = new[] { "Item2", "Item1" } }; var builder = Compat.CreateDataSourceExpressionBuilder <Tuple <int, int> >(options, false); Assert.Equal( "data.OrderBy(obj => obj.Item2).ThenBy(obj => obj.Item1)", builder.BuildLoadExpr().ToString() ); }
public void BuildLoadExpr_WithGuardNulls() { var expr = Compat.CreateDataSourceExpressionBuilder <Tuple <DateTime?> >(CreateFullStuffedLoadOptions(true)).BuildLoadExpr(); Assert.Equal( "data" // All selectors are guarded and use conversion to Nullable + $".Where(obj => ({FormatExpectedSelectorExpr(true, true)} == 123))" + $".OrderBy(obj => {FormatExpectedSelectorExpr(true, true)})" + ".Select(obj => new AnonType`1(" + $"I0 = {FormatExpectedSelectorExpr(true, true)}" + "))", expr.ToString() ); }
public void MultiIntervalGroupsSortedOnce() { var builder = Compat.CreateDataSourceExpressionBuilder <int>(new SampleLoadOptions { Group = new[] { new GroupingInfo { Selector = "this", GroupInterval = "a" }, new GroupingInfo { Selector = "this", GroupInterval = "b" } } }); Assert.Equal("data.OrderBy(obj => obj)", builder.BuildLoadExpr().ToString()); }
static string FormatExpectedSelectorExpr(bool convertToNullable, bool guardNulls) { var result = "obj.Item1.Value.Year"; if (convertToNullable) { result = Compat.ExpectedConvert(result, "Nullable`1"); } if (guardNulls) { result = $"IIF(((obj == null) OrElse (obj.Item1 == null)), null, {result})"; } return(result); }
public void Build_Sorting() { var builder = Compat.CreateDataSourceExpressionBuilder <Tuple <int, string> >(new SampleLoadOptions { Sort = new[] { new SortingInfo { Selector = "Item1" }, new SortingInfo { Selector = "Item2", Desc = true } } }); var expr = builder.BuildLoadExpr(); Assert.Equal("data.OrderBy(obj => obj.Item1).ThenByDescending(obj => obj.Item2)", expr.ToString()); }
public void BuildLoadGroupsExpr_NoGuardNulls() { var expr = Compat.CreateDataSourceExpressionBuilder <Tuple <DateTime?> >(CreateFullStuffedLoadOptions(false)).BuildLoadGroupsExpr(); Assert.Equal( // Only selectors that land in .Select() use conversion to Nullable "data" + $".Where(obj => ({FormatExpectedSelectorExpr(false, false)} == 123))" + $".GroupBy(obj => new AnonType`1(I0 = {FormatExpectedSelectorExpr(true, false)}))" + ".OrderBy(g => g.Key.I0)" + ".Select(g => new AnonType`4(" + "I0 = g.Count(), " + "I1 = g.Key.I0, " + $"I2 = g.Max(obj => {FormatExpectedSelectorExpr(true, false)}), " + $"I3 = g.Max(obj => {FormatExpectedSelectorExpr(true, false)})" + "))", expr.ToString() ); }
public void Struct() { TestFilter( new[] { new DataItemStruct { Value = 1 }, new DataItemStruct { Value = 2 }, }, "=", new DataItemStruct { Value = 1 }, ".Where(obj => Equals(" + Compat.ExpectedConvert("obj", "Object") + ", " + Compat.ExpectedConvert("{1}", "Object") + "))" ); }
public void PR202() { // https://github.com/DevExpress/DevExtreme.AspNet.Data/pull/202 var options = new SampleLoadOptions { DefaultSort = "item1", Sort = new[] { new SortingInfo { Selector = "ITEM1" } } }; var builder = Compat.CreateDataSourceExpressionBuilder <Tuple <int> >(options, false); Assert.Equal( "data.OrderBy(obj => obj.Item1)", builder.BuildLoadExpr().ToString() ); }
public void ValueTypeAndNull() { // Part of https://devexpress.com/issue=T616169 fix string CompileOperation(string op) { return(Compile <Tuple <int> >(new[] { "Item1", op, null }).Body.ToString()); } var expectedConvert = Compat.ExpectedConvert("obj.Item1", "Nullable`1"); Assert.Equal($"({expectedConvert} == null)", CompileOperation("=")); Assert.Equal($"({expectedConvert} != null)", CompileOperation("<>")); // https://stackoverflow.com/q/4399932 Assert.Equal("False", CompileOperation(">")); Assert.Equal("False", CompileOperation(">=")); Assert.Equal("False", CompileOperation("<")); Assert.Equal("False", CompileOperation("<=")); }
public void GuardNulls() { var data = new[] { // filtered out null, Tuple.Create <int?, string, DateTime?>(null, "zz", new DateTime(2000, 1, 1)), Tuple.Create <int?, string, DateTime?>(1, null, new DateTime(2000, 1, 1)), Tuple.Create <int?, string, DateTime?>(1, "zz", null), // kept Tuple.Create <int?, string, DateTime?>(1, "zz", new DateTime(2000, 1, 2)), Tuple.Create <int?, string, DateTime?>(1, "zz", new DateTime(2000, 1, 1)) }.AsQueryable(); var builder = Compat.CreateDataSourceExpressionBuilder(data, new SampleLoadOptions { Filter = new[] { new[] { "Item1", ">", "0" }, new[] { "Item2", "contains", "z" }, new[] { "Item2.Length", ">", "1" }, new[] { "Item3.Year", ">", "0" } }, Sort = new[] { new SortingInfo { Selector = "Item1" }, new SortingInfo { Selector = "Item2.Length" }, new SortingInfo { Selector = "Item3.Year" }, }, GuardNulls = true }); var expr = builder.BuildLoadExpr(); var result = data.Provider.CreateQuery <object>(expr).ToArray(); Assert.Equal(2, result.Length); }
public void DefaultSort() { var options = new SampleLoadOptions { DefaultSort = "Item1" }; var builder = Compat.CreateDataSourceExpressionBuilder <Tuple <int, int> >(options, false); Assert.Equal("data.OrderBy(obj => obj.Item1)", builder.BuildLoadExpr(false).ToString()); options.Sort = new[] { new SortingInfo { Selector = "Item2" } }; Assert.Equal("data.OrderBy(obj => obj.Item2).ThenBy(obj => obj.Item1)", builder.BuildLoadExpr(false).ToString()); options.Sort[0].Selector = "Item1"; Assert.Equal("data.OrderBy(obj => obj.Item1)", builder.BuildLoadExpr(false).ToString()); }
public void NoUnnecessaryOrderingForRemoteGroups() { var options = new SampleLoadOptions { RemoteGrouping = true, Group = new[] { new GroupingInfo { Selector = "Item1" } }, Sort = new[] { new SortingInfo { Selector = "Item2" } } }; var builder = Compat.CreateDataSourceExpressionBuilder <Tuple <int, int> >(options, false); var expr = builder.BuildLoadGroupsExpr().ToString(); Assert.StartsWith("data.GroupBy", expr); }
public void Build_CountQuery() { var builder = Compat.CreateDataSourceExpressionBuilder <int>(new SampleLoadOptions { Skip = 111, Take = 222, Filter = new object[] { "this", 123 }, Sort = new[] { new SortingInfo { Selector = "this" } }, }); var expr = builder.BuildCountExpr(); var text = expr.ToString(); Assert.Contains("Where", text); Assert.DoesNotContain("Skip", text); Assert.DoesNotContain("Take", text); Assert.DoesNotContain("OrderBy", text); Assert.Contains(".Count()", text); }
public void GroupInterval_Date() { string Compile <T>(string selector, bool guardNulls) { var compiler = new RemoteGroupExpressionCompiler <T>( guardNulls, new[] { new GroupingInfo { Selector = selector, GroupInterval = "year" }, new GroupingInfo { Selector = selector, GroupInterval = "quarter" }, new GroupingInfo { Selector = selector, GroupInterval = "month" }, new GroupingInfo { Selector = selector, GroupInterval = "day" }, new GroupingInfo { Selector = selector, GroupInterval = "dayOfWeek" }, new GroupingInfo { Selector = selector, GroupInterval = "hour" }, new GroupingInfo { Selector = selector, GroupInterval = "minute" }, new GroupingInfo { Selector = selector, GroupInterval = "second" } }, null, null ); return(compiler.Compile(CreateTargetParam <T>()).ToString()); } { var expr = Compile <DateTime>("this", false); Assert.Contains("I0 = obj.Year", expr); Assert.Contains("I1 = ((obj.Month + 2) / 3)", expr); Assert.Contains("I2 = obj.Month", expr); Assert.Contains("I3 = obj.Day", expr); Assert.Contains("I4 = " + Compat.ExpectedConvert("obj.DayOfWeek", "Int32"), expr); Assert.Contains("I5 = obj.Hour", expr); Assert.Contains("I6 = obj.Minute", expr); Assert.Contains("I7 = obj.Second", expr); } { var expr = Compile <DateTime?>("this", false); string Wrap(string coreSelector) { return(Compat.ExpectedConvert(coreSelector, "Nullable`1")); } Assert.Contains("I0 = " + Wrap("obj.Value.Year"), expr); Assert.Contains("I1 = " + Wrap("((obj.Value.Month + 2) / 3)"), expr); Assert.Contains("I2 = " + Wrap("obj.Value.Month"), expr); Assert.Contains("I3 = " + Wrap("obj.Value.Day"), expr); Assert.Contains("I4 = " + Wrap("obj.Value.DayOfWeek"), expr); Assert.Contains("I5 = " + Wrap("obj.Value.Hour"), expr); Assert.Contains("I6 = " + Wrap("obj.Value.Minute"), expr); Assert.Contains("I7 = " + Wrap("obj.Value.Second"), expr); } { var expr = Compile <Tuple <DateTime?> >("Item1", true); string Wrap(string coreSelector) { return($"IIF(((obj == null) OrElse (obj.Item1 == null)), null, {Compat.ExpectedConvert(coreSelector, "Nullable`1")})"); } Assert.Contains("I0 = " + Wrap("obj.Item1.Value.Year"), expr); Assert.Contains("I1 = " + Wrap("((obj.Item1.Value.Month + 2) / 3)"), expr); Assert.Contains("I2 = " + Wrap("obj.Item1.Value.Month"), expr); Assert.Contains("I3 = " + Wrap("obj.Item1.Value.Day"), expr); Assert.Contains("I4 = " + Wrap("obj.Item1.Value.DayOfWeek"), expr); Assert.Contains("I5 = " + Wrap("obj.Item1.Value.Hour"), expr); Assert.Contains("I6 = " + Wrap("obj.Item1.Value.Minute"), expr); Assert.Contains("I7 = " + Wrap("obj.Item1.Value.Second"), expr); } }
public void ExpandLinqSumType() { var sourceItem = new { SByte = SByte.MaxValue, Byte = Byte.MaxValue, Int16 = Int16.MaxValue, UInt16 = UInt16.MaxValue, Int32 = Int32.MaxValue, UInt32 = UInt32.MaxValue, Int64 = Int64.MaxValue / 2, UInt64 = UInt64.MaxValue, Single = Single.MaxValue, Double = Double.MaxValue / 2, Decimal = (Decimal.MaxValue - 1) / 2, SByteN = (SByte?)SByte.MaxValue, ByteN = (Byte?)Byte.MaxValue, Int16N = (Int16?)Int16.MaxValue, UInt16N = (UInt16?)UInt16.MaxValue, Int32N = (Int32?)Int32.MaxValue, UInt32N = (UInt32?)UInt32.MaxValue, Int64N = (Int64?)Int64.MaxValue / 2, UInt64N = (UInt64?)UInt64.MaxValue, SingleN = (Single?)Single.MaxValue, DoubleN = (Double?)Double.MaxValue / 2, DecimalN = ((Decimal?)Decimal.MaxValue - 1) / 2 }; var loadOptions = new SampleLoadOptions { GuardNulls = false, TotalSummary = new[] { nameof(sourceItem.SByte), nameof(sourceItem.Byte), nameof(sourceItem.Int16), nameof(sourceItem.UInt16), nameof(sourceItem.Int32), nameof(sourceItem.UInt32), nameof(sourceItem.Int64), nameof(sourceItem.UInt64), nameof(sourceItem.Single), nameof(sourceItem.Double), nameof(sourceItem.Decimal), nameof(sourceItem.SByteN), nameof(sourceItem.ByteN), nameof(sourceItem.Int16N), nameof(sourceItem.UInt16N), nameof(sourceItem.Int32N), nameof(sourceItem.UInt32N), nameof(sourceItem.Int64N), nameof(sourceItem.UInt64N), nameof(sourceItem.SingleN), nameof(sourceItem.DoubleN), nameof(sourceItem.DecimalN), } .Select(i => new SummaryInfo { Selector = i, SummaryType = "sum" }) .ToArray(), RemoteGrouping = true, ExpandLinqSumType = true }; var summary = DataSourceLoader.Load(new[] { sourceItem, sourceItem }, loadOptions).summary; var exprText = loadOptions.ExpressionLog.First(line => line.Contains("GroupBy")); Assert.Contains("Sum(obj => " + Compat.ExpectedConvert("obj.SByte", "Int64"), exprText); Assert.Contains("Sum(obj => " + Compat.ExpectedConvert("obj.Byte", "Int64"), exprText); Assert.Contains("Sum(obj => " + Compat.ExpectedConvert("obj.Int16", "Int64"), exprText); Assert.Contains("Sum(obj => " + Compat.ExpectedConvert("obj.UInt16", "Int64"), exprText); Assert.Contains("Sum(obj => " + Compat.ExpectedConvert("obj.Int32", "Int64"), exprText); Assert.Contains("Sum(obj => " + Compat.ExpectedConvert("obj.UInt32", "Int64"), exprText); Assert.Contains("Sum(obj => obj.Int64", exprText); Assert.Contains("Sum(obj => " + Compat.ExpectedConvert("obj.UInt64", "Decimal"), exprText); Assert.Contains("Sum(obj => " + Compat.ExpectedConvert("obj.Single", "Double"), exprText); Assert.Contains("Sum(obj => obj.Double", exprText); Assert.Contains("Sum(obj => obj.Decimal", exprText); Assert.Equal(2m * sourceItem.SByte, summary[0]); Assert.Equal(2m * sourceItem.Byte, summary[1]); Assert.Equal(2m * sourceItem.Int16, summary[2]); Assert.Equal(2m * sourceItem.UInt16, summary[3]); Assert.Equal(2m * sourceItem.Int32, summary[4]); Assert.Equal(2m * sourceItem.UInt32, summary[5]); Assert.Equal(2m * sourceItem.Int64, summary[6]); Assert.Equal(2m * sourceItem.UInt64, summary[7]); Assert.Equal(2d * sourceItem.Single, summary[8]); Assert.Equal(2d * sourceItem.Double, summary[9]); Assert.Equal(2m * sourceItem.Decimal, summary[10]); Assert.Equal(2m * sourceItem.SByteN, summary[11]); Assert.Equal(2m * sourceItem.ByteN, summary[12]); Assert.Equal(2m * sourceItem.Int16N, summary[13]); Assert.Equal(2m * sourceItem.UInt16N, summary[14]); Assert.Equal(2m * sourceItem.Int32N, summary[15]); Assert.Equal(2m * sourceItem.UInt32N, summary[16]); Assert.Equal(2m * sourceItem.Int64N, summary[17]); Assert.Equal(2m * sourceItem.UInt64N, summary[18]); Assert.Equal(2d * sourceItem.SingleN, summary[19]); Assert.Equal(2d * sourceItem.DoubleN, summary[20]); Assert.Equal(2m * sourceItem.DecimalN, summary[21]); }
public void Accessor_Guard_SingleComponent() { Assert.Equal($"IIF((t == null), null, {Compat.ExpectedConvert("t.Value", "Nullable`1")})", CompileAccessor(true, "Value")); Assert.Equal("IIF((t == null), null, t.Ref)", CompileAccessor(true, "Ref")); }