diff --git a/DCCS.Data.Source.Tests/ResultQueryableExtensionsTest.cs b/DCCS.Data.Source.Tests/ResultQueryableExtensionsTest.cs index bcf110d..274de3b 100644 --- a/DCCS.Data.Source.Tests/ResultQueryableExtensionsTest.cs +++ b/DCCS.Data.Source.Tests/ResultQueryableExtensionsTest.cs @@ -34,5 +34,36 @@ public void Should_create_Result() Assert.AreEqual(total, sut.Total); } + + [Test] + public void Should_create_Result_without_Total() + { + var total = 100; + var data = new Faker().Generate(total); + var sut = data.AsQueryable().ToResultWithoutTotal(new Params()); + Assert.IsNotNull(sut); + } + + + [Test] + public void Should_create_ResultWithoutTotal_to_less_results() + { + var total = 100; + var data = new Faker().Generate(total); + var sut = data.AsQueryable().ToResultWithoutTotal(new Params { Page = 1, Count = 10000 }); + Assert.AreEqual(100, sut.Data.Count()); + } + + [Test] + public void Should_create_ResultWithoutTotal_with_first_page() + { + var total = 100; + var data = new Faker().Generate(total); + // We request a none existing page, this should fallback in returning the first page + var sut = data.AsQueryable().ToResultWithoutTotal(new Params { Page = 1000, Count = 10 }); + Assert.AreEqual(1, sut.Page); + Assert.AreEqual(10, sut.Data.Count()); + } + } } diff --git a/DCCS.Data.Source/Params.cs b/DCCS.Data.Source/Params.cs index 8e0150e..5b33bbe 100644 --- a/DCCS.Data.Source/Params.cs +++ b/DCCS.Data.Source/Params.cs @@ -25,7 +25,5 @@ public Params(Params ps) public int? Count { get; set; } public string OrderBy { get; set; } public bool Desc { get; set; } - - } } diff --git a/DCCS.Data.Source/Result.cs b/DCCS.Data.Source/Result.cs index 908da12..76cf2e8 100644 --- a/DCCS.Data.Source/Result.cs +++ b/DCCS.Data.Source/Result.cs @@ -6,100 +6,24 @@ namespace DCCS.Data.Source { - public class Result : Params + public class Result : ResultWithoutTotal { - public IEnumerable Data { get; protected set; } - public int Total { get; set; } - - public Result(Params ps) : base(ps) - { } - - public Result(Params ps, IQueryable data) : base(ps) + public Result(Params ps, IQueryable data = null) : base(ps, data) { - SetData(data); } - public void SetData(IQueryable data) + public override void SetData(IQueryable data) { - var result = Sort(data); - - Total = result.Count(); + if (data == null) + throw new ArgumentNullException(nameof(data)); + Total = data.Count(); if (Count.HasValue) { Count = Math.Min(Count.Value, Total); } - - result = Paging(result); - - Data = result.ToArray(); + base.SetData(data); } - public Result Select(Expression> predicate) - { - return new Result(new Params - { - Count = Count, - OrderBy = OrderBy, - Desc = Desc, - Page = Page - }) - { - Data = Data.AsQueryable().Select(predicate) - }; - } - - protected IQueryable Sort(IQueryable data) - { - // Sortieren... - if (!string.IsNullOrWhiteSpace(OrderBy)) - { - return data.OrderBy($"{OrderBy} {(Desc ? "desc" : "")}"); - } - else if (data.Expression.Type != typeof(IOrderedQueryable)) - { - // Vor einem Skip (siehe unten) muß ein OrderBy aufgerufen werden. - // Ist keine Sortierung angegeben, müssen wir dennoch sortieren und behalten - // dabei die Reihenfolge bei. - return data.OrderBy(x => true); - } - - return data; - } - - protected IQueryable Paging(IQueryable data) - { - // Pagen... - IQueryable tempresult = null; // Wird für "Kann diese Seite überhaupt angezeigt werden" benötigt - if (Page.HasValue) - { - if (!Count.HasValue) throw new ArgumentNullException("Bei angegebener Seite (page) muss auch die Anzahl der Einträge (count) angegeben werden!"); - - //Manuel 24.10.2016 - //INFO: es wurde falsche ergebnisse geliefert weil "OrderBy>true" gefehlt hat. -> das sollte sich stephan nochmal anschauen - //Folgende anpassungen sind als Quickfix anzusehen und sollten noch optimiert werden - - var skip = (Page.Value - 1) * Count.Value; - var take = Count.Value; - - //Ohne OrderBy, da es eine Sortierung gibt - if (!string.IsNullOrWhiteSpace(OrderBy)) - { - tempresult = data.Skip(skip).Take(take); - } - //Mit OrderBy, da es keine Sortierung gibt - else - { - tempresult = data.Skip(skip).OrderBy(x => true).Take(take).OrderBy(x => true); - } - if (!tempresult.Any()) - { - Page = 1; - tempresult = data.Take(Count.Value); - } - } - - return (tempresult ?? new List().AsQueryable()); - - } + public int Total { get; set; } } } diff --git a/DCCS.Data.Source/ResultQueryableExtensions.cs b/DCCS.Data.Source/ResultQueryableExtensions.cs index 0d7d5ca..adaac5c 100644 --- a/DCCS.Data.Source/ResultQueryableExtensions.cs +++ b/DCCS.Data.Source/ResultQueryableExtensions.cs @@ -16,5 +16,14 @@ public static Result ToResult(this IQueryable source, Params ps) } return new Result(ps, source); } + + public static ResultWithoutTotal ToResultWithoutTotal(this IQueryable source, Params ps) + { + if (source == null) + { + throw new ArgumentNullException("source"); + } + return new ResultWithoutTotal(ps, source); + } } } diff --git a/DCCS.Data.Source/ResultWithoutTotal.cs b/DCCS.Data.Source/ResultWithoutTotal.cs new file mode 100644 index 0000000..6309a01 --- /dev/null +++ b/DCCS.Data.Source/ResultWithoutTotal.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Dynamic.Core; +using System.Linq.Expressions; + +namespace DCCS.Data.Source +{ + public class ResultWithoutTotal : Params + { + public IEnumerable Data { get; protected set; } + + public ResultWithoutTotal(Params ps) : base(ps) + { } + + public ResultWithoutTotal(Params ps, IQueryable data) : base(ps) + { + if (data != null) + SetData(data); + } + + public virtual void SetData(IQueryable data) + { + if (data == null) + throw new ArgumentNullException(nameof(data)); + var result = Sort(data); + + result = Paging(result); + Data = result.ToArray(); + } + + public Result Select(Expression> predicate) + { + return new Result(new Params + { + Count = Count, + OrderBy = OrderBy, + Desc = Desc, + Page = Page + }) + { + Data = Data.AsQueryable().Select(predicate) + }; + } + + protected IQueryable Sort(IQueryable data) + { + // Sortieren... + if (!string.IsNullOrWhiteSpace(OrderBy)) + { + return data.OrderBy($"{OrderBy} {(Desc ? "desc" : "")}"); + } + else if (data.Expression.Type != typeof(IOrderedQueryable)) + { + // Vor einem Skip (siehe unten) muß ein OrderBy aufgerufen werden. + // Ist keine Sortierung angegeben, müssen wir dennoch sortieren und behalten + // dabei die Reihenfolge bei. + return data.OrderBy(x => true); + } + + return data; + } + + protected IQueryable Paging(IQueryable data) + { + // Pagen... + IQueryable tempresult = null; // Wird für "Kann diese Seite überhaupt angezeigt werden" benötigt + if (Page.HasValue) + { + if (!Count.HasValue) throw new ArgumentNullException("Bei angegebener Seite (page) muss auch die Anzahl der Einträge (count) angegeben werden!"); + + //Manuel 24.10.2016 + //INFO: es wurde falsche ergebnisse geliefert weil "OrderBy>true" gefehlt hat. -> das sollte sich stephan nochmal anschauen + //Folgende anpassungen sind als Quickfix anzusehen und sollten noch optimiert werden + + var skip = (Page.Value - 1) * Count.Value; + var take = Count.Value; + + //Ohne OrderBy, da es eine Sortierung gibt + if (!string.IsNullOrWhiteSpace(OrderBy)) + { + tempresult = data.Skip(skip).Take(take); + } + //Mit OrderBy, da es keine Sortierung gibt + else + { + tempresult = data.Skip(skip).OrderBy(x => true).Take(take).OrderBy(x => true); + } + if (!tempresult.Any()) + { + Page = 1; + tempresult = data.Take(Count.Value); + } + } + + return (tempresult ?? new List().AsQueryable()); + + } + } +}