From 30efe918ca2cb228373364c301d36c6437a2aeba Mon Sep 17 00:00:00 2001 From: Michael Staib Date: Tue, 3 Sep 2024 16:30:01 +0200 Subject: [PATCH] Batch Paging Refinements (#7422) --- .../src/Core/CreateDataLoaderBranch.cs | 21 + src/GreenDonut/src/Core/DataLoaderBase.cs | 49 +- .../src/Core/DataLoaderExtensions.cs | 105 +- .../src/Core/DataLoaderFetchContext.cs | 50 +- src/GreenDonut/src/Core/GreenDonut.csproj | 6 +- src/GreenDonut/src/Core/IDataLoader.cs | 24 +- .../src/Core/Internals/DataLoaderHelper.cs | 105 + .../Projections/DefaultSelectorBuilder.cs | 4 +- .../src/Core/Projections/ExpressionHelpers.cs | 2 +- .../Core/Projections/ISelectionDataLoader.cs | 2 +- .../src/Core/Projections/ISelectorBuilder.cs | 4 +- .../src/Core/Projections/ISelectorQuery.cs | 0 .../Core/Projections/SelectionDataLoader.cs | 6 +- .../SelectionDataLoaderExtensions.cs | 31 +- .../Execution/HotChocolate.Execution.csproj | 12 + ...tChocolateExecutionDataLoaderExtensions.cs | 58 +- .../Projections/SelectionExpressionBuilder.cs | 2 +- .../FileBuilders/DataLoaderFileBuilder.cs | 3 +- .../Types.Analyzers/Models/DataLoaderInfo.cs | 17 + .../Models/DataLoaderParameterKind.cs | 1 + .../src/Types.Analyzers/WellKnownTypes.cs | 1 + .../Projections/ProjectableDataLoaderTests.cs | 42 +- ...aLoaderTests.Branches_Are_Merged_NET7_0.md | 32 + ...Tests.Brand_Details_Country_Name_NET7_0.md | 27 + ..._With_Details_As_Custom_Resolver_NET7_0.md | 27 + ...eDataLoaderTests.Brand_With_Name_NET7_0.md | 22 + ...leDataLoaderTests.Do_Not_Project_NET7_0.md | 22 + ...leDataLoaderTests.Force_A_Branch_NET7_0.md | 36 + ...derTests.Manual_Include_Of_Brand_NET7_0.md | 23 + ...ct_With_Name_And_Brand_With_Name_NET7_0.md | 26 + ...Tests.Project_And_Do_Not_Project_NET7_0.md | 28 + .../Types.Analyzers.Tests/DataLoaderTests.cs | 25 + .../test/Types.Analyzers.Tests/TestHelper.cs | 4 + .../Types/DataLoaders.cs | 11 +- ...er_With_PagingArguments_MatchesSnapshot.md | 101 + .../Pagination/HotChocolate.Pagination.sln | 7 + ...ePaginationBatchingDataLoaderExtensions.cs | 115 + ...aginationBatchingDataLoaderFetchContext.cs | 24 + .../HotChocolate.Pagination.Batching.csproj | 15 + .../Pagination.Batching/IPagingDataLoader.cs | 28 + .../Pagination.Batching/PagingDataLoader.cs | 39 + .../Expressions/ExpressionHelpers.cs | 332 +- .../HotChocolate.Pagination.Core.csproj | 2 +- .../Expressions/BatchQueryRewriter.cs | 173 - .../Extensions/PagingQueryableExtensions.cs | 122 +- .../PagingHelperIntegrationTests.cs | 159 +- .../PagingHelperTests.cs | 35 +- ...onPagingHelperTests.BatchPaging_First_5.md | 30 +- ...ionPagingHelperTests.BatchPaging_Last_5.md | 54 +- ...PagingHelperTests.Nested_Paging_First_2.md | 56 + ...ngHelperTests.Batch_Fetch_First_2_Items.md | 11149 +--------------- 51 files changed, 1743 insertions(+), 11526 deletions(-) create mode 100644 src/GreenDonut/src/Core/CreateDataLoaderBranch.cs create mode 100644 src/GreenDonut/src/Core/Internals/DataLoaderHelper.cs delete mode 100644 src/GreenDonut/src/Core/Projections/ISelectorQuery.cs create mode 100644 src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Branches_Are_Merged_NET7_0.md create mode 100644 src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Brand_Details_Country_Name_NET7_0.md create mode 100644 src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Brand_Details_Country_Name_With_Details_As_Custom_Resolver_NET7_0.md create mode 100644 src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Brand_With_Name_NET7_0.md create mode 100644 src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Do_Not_Project_NET7_0.md create mode 100644 src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Force_A_Branch_NET7_0.md create mode 100644 src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Manual_Include_Of_Brand_NET7_0.md create mode 100644 src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Product_With_Name_And_Brand_With_Name_NET7_0.md create mode 100644 src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Project_And_Do_Not_Project_NET7_0.md create mode 100644 src/HotChocolate/Core/test/Types.Analyzers.Tests/__snapshots__/DataLoaderTests.GenerateSource_BatchDataLoader_With_PagingArguments_MatchesSnapshot.md create mode 100644 src/HotChocolate/Pagination/src/Pagination.Batching/Extensions/HotChocolatePaginationBatchingDataLoaderExtensions.cs create mode 100644 src/HotChocolate/Pagination/src/Pagination.Batching/Extensions/HotChocolatePaginationBatchingDataLoaderFetchContext.cs create mode 100644 src/HotChocolate/Pagination/src/Pagination.Batching/HotChocolate.Pagination.Batching.csproj create mode 100644 src/HotChocolate/Pagination/src/Pagination.Batching/IPagingDataLoader.cs create mode 100644 src/HotChocolate/Pagination/src/Pagination.Batching/PagingDataLoader.cs delete mode 100644 src/HotChocolate/Pagination/src/Pagination.EntityFramework/Expressions/BatchQueryRewriter.cs create mode 100644 src/HotChocolate/Pagination/test/Pagination.EntityFramework.Tests/__snapshots__/IntegrationPagingHelperTests.Nested_Paging_First_2.md diff --git a/src/GreenDonut/src/Core/CreateDataLoaderBranch.cs b/src/GreenDonut/src/Core/CreateDataLoaderBranch.cs new file mode 100644 index 00000000000..6dd69ed5177 --- /dev/null +++ b/src/GreenDonut/src/Core/CreateDataLoaderBranch.cs @@ -0,0 +1,21 @@ +#if NET6_0_OR_GREATER +namespace GreenDonut; + +/// +/// Creates a branched DataLoader with a specific branch key. +/// +/// +/// The type of the DataLoader key. +/// +/// +/// The type of the DataLoader value. +/// +/// +/// The custom state that is passed into the factory. +/// +public delegate IDataLoader CreateDataLoaderBranch( + string branchKey, + IDataLoader dataLoader, + TState state) + where TKey : notnull; +#endif diff --git a/src/GreenDonut/src/Core/DataLoaderBase.cs b/src/GreenDonut/src/Core/DataLoaderBase.cs index bbd13e07d12..eeb1a9bfedd 100644 --- a/src/GreenDonut/src/Core/DataLoaderBase.cs +++ b/src/GreenDonut/src/Core/DataLoaderBase.cs @@ -1,7 +1,4 @@ using System.Collections.Immutable; -#if NET8_0_OR_GREATER -using GreenDonut.Projections; -#endif using static GreenDonut.NoopDataLoaderDiagnosticEventListener; using static GreenDonut.Errors; @@ -33,9 +30,9 @@ public abstract partial class DataLoaderBase private readonly int _maxBatchSize; private readonly IDataLoaderDiagnosticEvents _diagnosticEvents; private readonly CancellationToken _ct; -#if NET8_0_OR_GREATER - private ImmutableDictionary> _branches = - ImmutableDictionary>.Empty; +#if NET6_0_OR_GREATER + private ImmutableDictionary _branches = + ImmutableDictionary.Empty; #endif private Batch? _currentBatch; @@ -80,14 +77,27 @@ protected DataLoaderBase(IBatchScheduler batchScheduler, DataLoaderOptions? opti public IImmutableDictionary ContextData { get; set; } = ImmutableDictionary.Empty; - private protected virtual bool AllowCachePropagation => true; + /// + /// Specifies if the values fetched by this DataLoader + /// are propagated through the cache. + /// + protected virtual bool AllowCachePropagation => true; - private protected virtual bool AllowBranching => true; + /// + /// Specifies if this DataLoader allows branching. + /// + protected virtual bool AllowBranching => true; - internal IBatchScheduler BatchScheduler + /// + /// Gets the batch scheduler of this DataLoader. + /// + protected internal IBatchScheduler BatchScheduler => _batchScheduler; - internal DataLoaderOptions Options + /// + /// Gets the options of this DataLoader. + /// + protected internal DataLoaderOptions Options => new() { MaxBatchSize = _maxBatchSize, @@ -252,11 +262,24 @@ public void Set(TKey key, Task value) Cache.TryAdd(cacheKey, new Promise(value)); } } -#if NET8_0_OR_GREATER +#if NET6_0_OR_GREATER /// - public ISelectionDataLoader Branch(string key) + public IDataLoader Branch( + string key, + CreateDataLoaderBranch createBranch, + TState state) { + if (string.IsNullOrEmpty(key)) + { + throw new ArgumentException("Value cannot be null or empty.", nameof(key)); + } + + if (createBranch == null) + { + throw new ArgumentNullException(nameof(createBranch)); + } + if(!AllowBranching) { throw new InvalidOperationException( @@ -269,7 +292,7 @@ public ISelectionDataLoader Branch(string key) { if (!_branches.TryGetValue(key, out branch)) { - var newBranch = new SelectionDataLoader(this, key); + var newBranch = createBranch(key, this, state); _branches = _branches.Add(key, newBranch); return newBranch; } diff --git a/src/GreenDonut/src/Core/DataLoaderExtensions.cs b/src/GreenDonut/src/Core/DataLoaderExtensions.cs index 85611539332..9a64e0c52aa 100644 --- a/src/GreenDonut/src/Core/DataLoaderExtensions.cs +++ b/src/GreenDonut/src/Core/DataLoaderExtensions.cs @@ -1,5 +1,4 @@ using System.Collections.Immutable; -using System.Diagnostics.CodeAnalysis; namespace GreenDonut; @@ -339,6 +338,110 @@ public static IDataLoader TrySetState( return dataLoader; } + /// + /// Gets a state value from the or + /// creates a new one and stores it as state on the . + /// + /// + /// The data loader instance. + /// + /// + /// A factory that creates the new state value. + /// + /// + /// The key type of the DataLoader. + /// + /// + /// The value type of the DataLoader. + /// + /// + /// The state type. + /// + /// + /// Returns the state value. + /// + /// + /// Throws if is null. + /// + public static TState GetOrSetState( + this IDataLoader dataLoader, + Func createValue) + where TKey : notnull + { + if (dataLoader is null) + { + throw new ArgumentNullException(nameof(dataLoader)); + } + + var key = typeof(TState).FullName ?? typeof(TState).Name; + + if(!dataLoader.ContextData.TryGetValue(key, out var internalValue)) + { + internalValue = createValue(key); + dataLoader.ContextData = dataLoader.ContextData.SetItem(key, internalValue); + } + + return (TState)internalValue!; + } + + /// + /// Gets a state value from the or + /// creates a new one and stores it as state on the . + /// + /// + /// The data loader instance. + /// + /// + /// The state key. + /// + /// + /// A factory that creates the new state value. + /// + /// + /// The key type of the DataLoader. + /// + /// + /// The value type of the DataLoader. + /// + /// + /// The state type. + /// + /// + /// Returns the state value. + /// + /// + /// Throws if is null. + /// + /// + /// Throws if is null or empty. + /// + public static TState GetOrSetState( + this IDataLoader dataLoader, + string key, + Func createValue) + where TKey : notnull + { + if (dataLoader is null) + { + throw new ArgumentNullException(nameof(dataLoader)); + } + + if (string.IsNullOrEmpty(key)) + { + throw new ArgumentException( + "The key must not be null or empty.", + nameof(key)); + } + + if(!dataLoader.ContextData.TryGetValue(key, out var internalValue)) + { + internalValue = createValue(key); + dataLoader.ContextData = dataLoader.ContextData.SetItem(key, internalValue); + } + + return (TState)internalValue!; + } + /// /// Adds the value to a collection that is stored on the DataLoader state. /// diff --git a/src/GreenDonut/src/Core/DataLoaderFetchContext.cs b/src/GreenDonut/src/Core/DataLoaderFetchContext.cs index 38c8a646a8f..4a4535ecaae 100644 --- a/src/GreenDonut/src/Core/DataLoaderFetchContext.cs +++ b/src/GreenDonut/src/Core/DataLoaderFetchContext.cs @@ -1,6 +1,8 @@ using System.Collections.Immutable; -using System.Diagnostics.CodeAnalysis; #if NET8_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif +#if NET6_0_OR_GREATER using GreenDonut.Projections; #endif @@ -21,6 +23,18 @@ public readonly struct DataLoaderFetchContext( { public IImmutableDictionary ContextData { get; } = contextData; + /// + /// Gets a value from the DataLoader state snapshot. + /// + /// + /// The type of the state value. + /// + /// + /// Returns the state value if it exists. + /// + public TState? GetState() + => GetState(typeof(TState).FullName ?? typeof(TState).Name); + /// /// Gets a value from the DataLoader state snapshot. /// @@ -43,6 +57,21 @@ public readonly struct DataLoaderFetchContext( return default; } + /// + /// Gets a required value from the DataLoader state snapshot. + /// + /// + /// The type of the state value. + /// + /// + /// Returns the state value if it exists. + /// + /// + /// Throws an exception if the state value does not exist. + /// + public TState GetRequiredState() + => GetRequiredState(typeof(TState).FullName ?? typeof(TState).Name); + /// /// Gets a required value from the DataLoader state snapshot. /// @@ -69,6 +98,21 @@ public TState GetRequiredState(string key) $"The state `{key}` is not available on the DataLoader."); } + /// + /// Gets a value from the DataLoader state snapshot or returns a default value. + /// + /// + /// The default value to return if the state value does not exist. + /// + /// + /// The type of the state value. + /// + /// + /// Returns the state value if it exists. + /// + public TState GetStateOrDefault(TState defaultValue) + => GetStateOrDefault(typeof(TState).FullName ?? typeof(TState).Name, defaultValue); + /// /// Gets a value from the DataLoader state snapshot or returns a default value. /// @@ -93,7 +137,7 @@ public TState GetStateOrDefault(string key, TState defaultValue) return defaultValue; } -#if NET8_0_OR_GREATER +#if NET6_0_OR_GREATER /// /// Gets the selector builder from the DataLoader state snapshot. @@ -102,7 +146,9 @@ public TState GetStateOrDefault(string key, TState defaultValue) /// /// Returns the selector builder if it exists. /// +#if NET8_0_OR_GREATER [Experimental(Experiments.Projections)] +#endif public ISelectorBuilder GetSelector() { DefaultSelectorBuilder context; diff --git a/src/GreenDonut/src/Core/GreenDonut.csproj b/src/GreenDonut/src/Core/GreenDonut.csproj index 2cbd3ba18f2..e3b8389ee65 100644 --- a/src/GreenDonut/src/Core/GreenDonut.csproj +++ b/src/GreenDonut/src/Core/GreenDonut.csproj @@ -4,9 +4,13 @@ GreenDonut GreenDonut GreenDonut - Green Donut is a port of facebook's DataLoader utility, written in C# for .NET Core and .NET Framework. + GreenDonut is a port of facebook's DataLoader utility, written in C# for .NET Core and .NET Framework. + + + + diff --git a/src/GreenDonut/src/Core/IDataLoader.cs b/src/GreenDonut/src/Core/IDataLoader.cs index d596194f2c4..4bf0ddc2343 100644 --- a/src/GreenDonut/src/Core/IDataLoader.cs +++ b/src/GreenDonut/src/Core/IDataLoader.cs @@ -6,15 +6,18 @@ namespace GreenDonut; /// +/// /// A DataLoader creates a public API for loading data from a /// particular data back-end with unique keys such as the `id` column of a /// SQL table or document name in a MongoDB database, given a batch loading /// function. -- facebook -/// +/// +/// /// Each DataLoader instance contains a unique memoized cache. Use /// caution when used in long-lived applications or those which serve many /// users with different access permissions and consider creating a new /// instance per web request. -- facebook +/// /// public interface IDataLoader { @@ -162,18 +165,25 @@ public interface IDataLoader /// void Set(TKey key, Task value); -#if NET8_0_OR_GREATER +#if NET6_0_OR_GREATER /// - /// Branches the current DataLoader to allow for selections - /// to be applied to the data fetching. + /// Branches the current DataLoader. /// /// /// A unique key to identify the branch. /// + /// + /// Creates the branch of the current DataLoader. + /// + /// + /// A custom state object that is passed to the branch factory. + /// /// - /// A new DataLoader instance which allows for selections to be - /// applied to the data fetching. + /// A new DataLoader instance. /// - ISelectionDataLoader Branch(string key); + IDataLoader Branch( + string key, + CreateDataLoaderBranch createBranch, + TState state); #endif } diff --git a/src/GreenDonut/src/Core/Internals/DataLoaderHelper.cs b/src/GreenDonut/src/Core/Internals/DataLoaderHelper.cs new file mode 100644 index 00000000000..41a8942074f --- /dev/null +++ b/src/GreenDonut/src/Core/Internals/DataLoaderHelper.cs @@ -0,0 +1,105 @@ +namespace GreenDonut.Internals; + +/// +/// This helper allows to access internal members of the +/// +/// for branching purposes. +/// +public static class DataLoaderHelper +{ + /// + /// Gets the options of the . + /// + /// + /// The instance. + /// + /// + /// The key type. + /// + /// + /// The value type. + /// + /// + /// Returns the options of the . + /// + public static DataLoaderOptions GetOptions( + DataLoaderBase dataLoader) + where TKey : notnull + => dataLoader.Options; + + /// + /// Gets the batch scheduler of the . + /// + /// + /// The instance. + /// + /// + /// The key type. + /// + /// + /// The value type. + /// + /// + /// Returns the batch scheduler of the . + /// + public static IBatchScheduler GetBatchScheduler( + DataLoaderBase dataLoader) + where TKey : notnull + => dataLoader.BatchScheduler; + + /// + /// Gets the cache key type of the . + /// + /// + /// The instance. + /// + /// + /// The key type. + /// + /// + /// The value type. + /// + /// + /// Returns the cache key type of the . + /// + public static string GetCacheKeyType( + DataLoaderBase dataLoader) + where TKey : notnull + => dataLoader.CacheKeyType; + + /// + /// Fetches the data for the provided keys by using the fetch method of + /// the provided . + /// + /// + /// The instance. + /// + /// + /// The keys for which the data shall be fetched. + /// + /// + /// The results that shall be filled with the fetched data. + /// + /// + /// The fetch context that shall be used for the fetch operation. + /// + /// + /// The cancellation token that shall be used for the fetch operation. + /// + /// + /// The key type. + /// + /// + /// The value type. + /// + /// + /// Returns the task representing the fetch operation. + /// + public static ValueTask FetchAsync( + DataLoaderBase dataLoader, + IReadOnlyList keys, + Memory> results, + DataLoaderFetchContext context, + CancellationToken cancellationToken) where TKey : notnull + => dataLoader.FetchAsync(keys, results, context, cancellationToken); +} diff --git a/src/GreenDonut/src/Core/Projections/DefaultSelectorBuilder.cs b/src/GreenDonut/src/Core/Projections/DefaultSelectorBuilder.cs index 57458337a4b..ca30af4313c 100644 --- a/src/GreenDonut/src/Core/Projections/DefaultSelectorBuilder.cs +++ b/src/GreenDonut/src/Core/Projections/DefaultSelectorBuilder.cs @@ -1,10 +1,12 @@ -#if NET8_0_OR_GREATER +#if NET6_0_OR_GREATER using System.Diagnostics.CodeAnalysis; using System.Linq.Expressions; namespace GreenDonut.Projections; +#if NET8_0_OR_GREATER [Experimental(Experiments.Projections)] +#endif internal sealed class DefaultSelectorBuilder : ISelectorBuilder { private LambdaExpression? _expression; diff --git a/src/GreenDonut/src/Core/Projections/ExpressionHelpers.cs b/src/GreenDonut/src/Core/Projections/ExpressionHelpers.cs index d5ce73c4ead..5b9640ee071 100644 --- a/src/GreenDonut/src/Core/Projections/ExpressionHelpers.cs +++ b/src/GreenDonut/src/Core/Projections/ExpressionHelpers.cs @@ -1,4 +1,4 @@ -#if NET8_0_OR_GREATER +#if NET6_0_OR_GREATER using System.Linq.Expressions; using System.Reflection; diff --git a/src/GreenDonut/src/Core/Projections/ISelectionDataLoader.cs b/src/GreenDonut/src/Core/Projections/ISelectionDataLoader.cs index b8727a0cfe0..04c34f05945 100644 --- a/src/GreenDonut/src/Core/Projections/ISelectionDataLoader.cs +++ b/src/GreenDonut/src/Core/Projections/ISelectionDataLoader.cs @@ -1,4 +1,4 @@ -#if NET8_0_OR_GREATER +#if NET6_0_OR_GREATER namespace GreenDonut.Projections; diff --git a/src/GreenDonut/src/Core/Projections/ISelectorBuilder.cs b/src/GreenDonut/src/Core/Projections/ISelectorBuilder.cs index bfac37e6690..0733a3ebd0e 100644 --- a/src/GreenDonut/src/Core/Projections/ISelectorBuilder.cs +++ b/src/GreenDonut/src/Core/Projections/ISelectorBuilder.cs @@ -1,4 +1,4 @@ -#if NET8_0_OR_GREATER +#if NET6_0_OR_GREATER using System.Diagnostics.CodeAnalysis; using System.Linq.Expressions; @@ -9,7 +9,9 @@ namespace GreenDonut.Projections; /// by adding expressions that will be merged into a /// single selector expression. /// +#if NET8_0_OR_GREATER [Experimental(Experiments.Projections)] +#endif public interface ISelectorBuilder { /// diff --git a/src/GreenDonut/src/Core/Projections/ISelectorQuery.cs b/src/GreenDonut/src/Core/Projections/ISelectorQuery.cs deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/GreenDonut/src/Core/Projections/SelectionDataLoader.cs b/src/GreenDonut/src/Core/Projections/SelectionDataLoader.cs index 561b017fc96..67271f86479 100644 --- a/src/GreenDonut/src/Core/Projections/SelectionDataLoader.cs +++ b/src/GreenDonut/src/Core/Projections/SelectionDataLoader.cs @@ -1,4 +1,4 @@ -#if NET8_0_OR_GREATER +#if NET6_0_OR_GREATER namespace GreenDonut.Projections; internal sealed class SelectionDataLoader @@ -21,9 +21,9 @@ public SelectionDataLoader( protected internal override string CacheKeyType { get; } - private protected override bool AllowCachePropagation => false; + protected override bool AllowCachePropagation => false; - private protected override bool AllowBranching => false; + protected override bool AllowBranching => false; protected internal override ValueTask FetchAsync( IReadOnlyList keys, diff --git a/src/GreenDonut/src/Core/Projections/SelectionDataLoaderExtensions.cs b/src/GreenDonut/src/Core/Projections/SelectionDataLoaderExtensions.cs index bf888d0ff6c..fbea2470039 100644 --- a/src/GreenDonut/src/Core/Projections/SelectionDataLoaderExtensions.cs +++ b/src/GreenDonut/src/Core/Projections/SelectionDataLoaderExtensions.cs @@ -1,4 +1,4 @@ -#if NET8_0_OR_GREATER +#if NET6_0_OR_GREATER using System.Diagnostics.CodeAnalysis; using System.Linq.Expressions; using System.Reflection; @@ -9,7 +9,9 @@ namespace GreenDonut.Projections; /// /// Data loader extensions for projections. /// +#if NET8_0_OR_GREATER [Experimental(Experiments.Projections)] +#endif public static class SelectionDataLoaderExtensions { /// @@ -48,21 +50,22 @@ public static ISelectionDataLoader Select( throw new ArgumentNullException(nameof(selector)); } - DefaultSelectorBuilder context; - var branch = dataLoader.Branch(selector.ToString()); - if (branch.ContextData.TryGetValue(typeof(ISelectorBuilder).FullName!, out var value) - && value is DefaultSelectorBuilder casted) - { - context = casted; - } - else + var branchKey = selector.ToString(); + return (ISelectionDataLoader)dataLoader.Branch(branchKey, CreateBranch, selector); + + static IDataLoader CreateBranch( + string key, + IDataLoader dataLoader, + Expression> selector) { - context = new DefaultSelectorBuilder(); + var branch = new SelectionDataLoader( + (DataLoaderBase)dataLoader, + key); + var context = new DefaultSelectorBuilder(); + branch.ContextData = branch.ContextData.SetItem(typeof(ISelectorBuilder).FullName!, context); + context.Add(selector); + return branch; } - - context.Add(selector); - branch.ContextData = branch.ContextData.SetItem(typeof(ISelectorBuilder).FullName!, context); - return branch; } /// diff --git a/src/HotChocolate/Core/src/Execution/HotChocolate.Execution.csproj b/src/HotChocolate/Core/src/Execution/HotChocolate.Execution.csproj index 9bb026fa181..a29ce96f31f 100644 --- a/src/HotChocolate/Core/src/Execution/HotChocolate.Execution.csproj +++ b/src/HotChocolate/Core/src/Execution/HotChocolate.Execution.csproj @@ -39,6 +39,18 @@ + + + + + + + + + + + + diff --git a/src/HotChocolate/Core/src/Execution/Projections/HotChocolateExecutionDataLoaderExtensions.cs b/src/HotChocolate/Core/src/Execution/Projections/HotChocolateExecutionDataLoaderExtensions.cs index 6e901be64d5..70db900e8bc 100644 --- a/src/HotChocolate/Core/src/Execution/Projections/HotChocolateExecutionDataLoaderExtensions.cs +++ b/src/HotChocolate/Core/src/Execution/Projections/HotChocolateExecutionDataLoaderExtensions.cs @@ -1,4 +1,4 @@ -#if NET8_0_OR_GREATER +#if NET6_0_OR_GREATER #nullable enable using System.Diagnostics.CodeAnalysis; @@ -6,15 +6,39 @@ using HotChocolate.Execution; using HotChocolate.Execution.Processing; using HotChocolate.Execution.Projections; +using HotChocolate.Pagination; // ReSharper disable once CheckNamespace namespace GreenDonut.Projections; +/// +/// Provides extension methods for projection on DataLoader. +/// +#if NET8_0_OR_GREATER [Experimental(Experiments.Projections)] +#endif public static class HotChocolateExecutionDataLoaderExtensions { private static readonly SelectionExpressionBuilder _builder = new(); + /// + /// Selects the fields that where selected in the GraphQL selection tree. + /// + /// + /// The data loader. + /// + /// + /// The selection that shall be applied to the data loader. + /// + /// + /// The key type. + /// + /// + /// The value type. + /// + /// + /// Returns a new data loader that applies the selection. + /// public static ISelectionDataLoader Select( this IDataLoader dataLoader, ISelection selection) @@ -28,5 +52,37 @@ public static ISelectionDataLoader Select( _builder); return dataLoader.Select(expression); } + + /// + /// Selects the fields that where selected in the GraphQL selection tree. + /// + /// + /// The data loader. + /// + /// + /// The selection that shall be applied to the data loader. + /// + /// + /// The key type. + /// + /// + /// The value type. + /// + /// + /// Returns a new data loader that applies the selection. + /// + public static IPagingDataLoader Select( + this IPagingDataLoader dataLoader, + ISelection selection) + where TKey : notnull + { + var key = $"{dataLoader.GetType().FullName!}.{selection.Id}"; + var expression = selection.DeclaringOperation + .GetOrAddState>, SelectionExpressionBuilder>( + key, + (_, b) => b.BuildExpression(selection), + _builder); + return HotChocolatePaginationBatchingDataLoaderExtensions.Select(dataLoader, expression); + } } #endif diff --git a/src/HotChocolate/Core/src/Execution/Projections/SelectionExpressionBuilder.cs b/src/HotChocolate/Core/src/Execution/Projections/SelectionExpressionBuilder.cs index 36cf4df5d1d..240fcffd308 100644 --- a/src/HotChocolate/Core/src/Execution/Projections/SelectionExpressionBuilder.cs +++ b/src/HotChocolate/Core/src/Execution/Projections/SelectionExpressionBuilder.cs @@ -1,4 +1,4 @@ -#if NET8_0_OR_GREATER +#if NET6_0_OR_GREATER using System.Collections.Immutable; using System.Linq.Expressions; using System.Reflection; diff --git a/src/HotChocolate/Core/src/Types.Analyzers/FileBuilders/DataLoaderFileBuilder.cs b/src/HotChocolate/Core/src/Types.Analyzers/FileBuilders/DataLoaderFileBuilder.cs index e8e8ac951af..5f283518d5b 100644 --- a/src/HotChocolate/Core/src/Types.Analyzers/FileBuilders/DataLoaderFileBuilder.cs +++ b/src/HotChocolate/Core/src/Types.Analyzers/FileBuilders/DataLoaderFileBuilder.cs @@ -254,7 +254,8 @@ public void WriteDataLoaderLoadMethod( isScoped ? "scope.ServiceProvider" : "_services", parameter.Type.ToFullyQualified()); } - else if (parameter.Kind is DataLoaderParameterKind.SelectorBuilder) + else if (parameter.Kind is DataLoaderParameterKind.SelectorBuilder + || parameter.Kind is DataLoaderParameterKind.PagingArguments) { _writer.WriteIndentedLine( "var {0} = context.GetRequiredState<{1}>(\"{2}\");", diff --git a/src/HotChocolate/Core/src/Types.Analyzers/Models/DataLoaderInfo.cs b/src/HotChocolate/Core/src/Types.Analyzers/Models/DataLoaderInfo.cs index ee3b9232c21..9f8992030aa 100644 --- a/src/HotChocolate/Core/src/Types.Analyzers/Models/DataLoaderInfo.cs +++ b/src/HotChocolate/Core/src/Types.Analyzers/Models/DataLoaderInfo.cs @@ -175,6 +175,17 @@ private static ImmutableArray CreateParameters(IMethodS continue; } + if (IsPagingArguments(parameter)) + { + builder.Add( + new DataLoaderParameterInfo( + $"p{i}", + parameter, + DataLoaderParameterKind.PagingArguments, + WellKnownTypes.PagingArguments)); + continue; + } + var stateKey = parameter.GetDataLoaderStateKey(); // if the parameter is annotated as a state attribute we will get here a state key. @@ -212,6 +223,12 @@ private static bool IsSelectorBuilder(IParameterSymbol parameter) return string.Equals(typeName, WellKnownTypes.SelectorBuilder, StringComparison.Ordinal); } + private static bool IsPagingArguments(IParameterSymbol parameter) + { + var typeName = parameter.Type.ToDisplayString(); + return string.Equals(typeName, WellKnownTypes.PagingArguments, StringComparison.Ordinal); + } + public static bool IsKeyValuePair(ITypeSymbol returnTypeSymbol, ITypeSymbol keyType, ITypeSymbol valueType) { if (returnTypeSymbol is INamedTypeSymbol namedTypeSymbol diff --git a/src/HotChocolate/Core/src/Types.Analyzers/Models/DataLoaderParameterKind.cs b/src/HotChocolate/Core/src/Types.Analyzers/Models/DataLoaderParameterKind.cs index cdb2221b672..15d34d66acc 100644 --- a/src/HotChocolate/Core/src/Types.Analyzers/Models/DataLoaderParameterKind.cs +++ b/src/HotChocolate/Core/src/Types.Analyzers/Models/DataLoaderParameterKind.cs @@ -7,4 +7,5 @@ public enum DataLoaderParameterKind ContextData = 2, CancellationToken = 3, SelectorBuilder = 4, + PagingArguments = 5 } diff --git a/src/HotChocolate/Core/src/Types.Analyzers/WellKnownTypes.cs b/src/HotChocolate/Core/src/Types.Analyzers/WellKnownTypes.cs index 5ec64598186..9595a0df611 100644 --- a/src/HotChocolate/Core/src/Types.Analyzers/WellKnownTypes.cs +++ b/src/HotChocolate/Core/src/Types.Analyzers/WellKnownTypes.cs @@ -67,6 +67,7 @@ public static class WellKnownTypes public const string KeyValuePair = "System.Collections.Generic.KeyValuePair"; public const string EnumerableExtensions = "System.Linq.Enumerable"; public const string SelectorBuilder = "GreenDonut.Projections.ISelectorBuilder"; + public const string PagingArguments = "HotChocolate.Pagination.PagingArguments"; public static HashSet TypeClass { get; } = [ diff --git a/src/HotChocolate/Core/test/Execution.Tests/Projections/ProjectableDataLoaderTests.cs b/src/HotChocolate/Core/test/Execution.Tests/Projections/ProjectableDataLoaderTests.cs index 2c66f65716d..38de3237506 100644 --- a/src/HotChocolate/Core/test/Execution.Tests/Projections/ProjectableDataLoaderTests.cs +++ b/src/HotChocolate/Core/test/Execution.Tests/Projections/ProjectableDataLoaderTests.cs @@ -1,4 +1,4 @@ -#if NET8_0_OR_GREATER +#if NET7_0_OR_GREATER using CookieCrumble; using GreenDonut; using GreenDonut.Projections; @@ -44,7 +44,11 @@ public async Task Brand_With_Name() } """); +#if NET8_0_OR_GREATER Snapshot.Create() +#else + Snapshot.Create(postFix: "NET7_0") +#endif .AddSql(queries) .AddResult(result) .MatchMarkdownSnapshot(); @@ -75,7 +79,11 @@ public async Task Manual_Include_Of_Brand() } """); +#if NET8_0_OR_GREATER Snapshot.Create() +#else + Snapshot.Create(postFix: "NET7_0") +#endif .AddSql(queries) .AddResult(result) .MatchMarkdownSnapshot(); @@ -110,7 +118,11 @@ public async Task Manual_Include_And_Observe_Brand() } """); +#if NET8_0_OR_GREATER Snapshot.Create() +#else + Snapshot.Create(postFix: "NET7_0") +#endif .AddSql(queries) .AddResult(result) .MatchMarkdownSnapshot(); @@ -141,7 +153,11 @@ public async Task Do_Not_Project() } """); +#if NET8_0_OR_GREATER Snapshot.Create() +#else + Snapshot.Create(postFix: "NET7_0") +#endif .AddSql(queries) .AddResult(result) .MatchMarkdownSnapshot(); @@ -175,7 +191,11 @@ public async Task Project_And_Do_Not_Project() } """); +#if NET8_0_OR_GREATER Snapshot.Create() +#else + Snapshot.Create(postFix: "NET7_0") +#endif .AddSql(queries) .AddResult(result) .MatchMarkdownSnapshot(); @@ -209,7 +229,11 @@ public async Task Product_With_Name_And_Brand_With_Name() } """); +#if NET8_0_OR_GREATER Snapshot.Create() +#else + Snapshot.Create(postFix: "NET7_0") +#endif .AddSql(queries) .AddResult(result) .MatchMarkdownSnapshot(); @@ -249,7 +273,11 @@ public async Task Force_A_Branch() } """); +#if NET8_0_OR_GREATER Snapshot.Create() +#else + Snapshot.Create(postFix: "NET7_0") +#endif .AddSql(queries) .AddResult(result) .MatchMarkdownSnapshot(); @@ -289,7 +317,11 @@ public async Task Branches_Are_Merged() } """); +#if NET8_0_OR_GREATER Snapshot.Create() +#else + Snapshot.Create(postFix: "NET7_0") +#endif .AddSql(queries) .AddResult(result) .MatchMarkdownSnapshot(); @@ -325,7 +357,11 @@ public async Task Brand_Details_Country_Name() } """); +#if NET8_0_OR_GREATER Snapshot.Create() +#else + Snapshot.Create(postFix: "NET7_0") +#endif .AddSql(queries) .AddResult(result) .MatchMarkdownSnapshot(); @@ -362,7 +398,11 @@ public async Task Brand_Details_Country_Name_With_Details_As_Custom_Resolver() } """); +#if NET8_0_OR_GREATER Snapshot.Create() +#else + Snapshot.Create(postFix: "NET7_0") +#endif .AddSql(queries) .AddResult(result) .MatchMarkdownSnapshot(); diff --git a/src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Branches_Are_Merged_NET7_0.md b/src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Branches_Are_Merged_NET7_0.md new file mode 100644 index 00000000000..185b19dd69f --- /dev/null +++ b/src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Branches_Are_Merged_NET7_0.md @@ -0,0 +1,32 @@ +# Branches_Are_Merged + +## SQL + +```text +SELECT p."Name", b."Name", p."Id" +FROM "Products" AS p +INNER JOIN "Brands" AS b ON p."BrandId" = b."Id" +WHERE p."Id" IN (1, 2) +``` + +## Result + +```json +{ + "data": { + "a": { + "name": "Product 0-0", + "brand": { + "name": "Brand0" + } + }, + "b": { + "name": "Product 0-1", + "brand": { + "name": "Brand0" + } + } + } +} +``` + diff --git a/src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Brand_Details_Country_Name_NET7_0.md b/src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Brand_Details_Country_Name_NET7_0.md new file mode 100644 index 00000000000..a5a7f99d878 --- /dev/null +++ b/src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Brand_Details_Country_Name_NET7_0.md @@ -0,0 +1,27 @@ +# Brand_Details_Country_Name + +## SQL + +```text +SELECT b."Name", b."Details_Country_Name" AS "Name", b."Id" +FROM "Brands" AS b +WHERE b."Id" = 1 +``` + +## Result + +```json +{ + "data": { + "brandById": { + "name": "Brand0", + "details": { + "country": { + "name": "Country0" + } + } + } + } +} +``` + diff --git a/src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Brand_Details_Country_Name_With_Details_As_Custom_Resolver_NET7_0.md b/src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Brand_Details_Country_Name_With_Details_As_Custom_Resolver_NET7_0.md new file mode 100644 index 00000000000..bd92975e965 --- /dev/null +++ b/src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Brand_Details_Country_Name_With_Details_As_Custom_Resolver_NET7_0.md @@ -0,0 +1,27 @@ +# Brand_Details_Country_Name_With_Details_As_Custom_Resolver + +## SQL + +```text +SELECT b."Name", b."Id" +FROM "Brands" AS b +WHERE b."Id" = 1 +``` + +## Result + +```json +{ + "data": { + "brandById": { + "name": "Brand0", + "details": { + "country": { + "name": "Germany" + } + } + } + } +} +``` + diff --git a/src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Brand_With_Name_NET7_0.md b/src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Brand_With_Name_NET7_0.md new file mode 100644 index 00000000000..d9a75f58b57 --- /dev/null +++ b/src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Brand_With_Name_NET7_0.md @@ -0,0 +1,22 @@ +# Brand_With_Name + +## SQL + +```text +SELECT b."Name", b."Id" +FROM "Brands" AS b +WHERE b."Id" = 1 +``` + +## Result + +```json +{ + "data": { + "brandById": { + "name": "Brand0" + } + } +} +``` + diff --git a/src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Do_Not_Project_NET7_0.md b/src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Do_Not_Project_NET7_0.md new file mode 100644 index 00000000000..dc5a17e0569 --- /dev/null +++ b/src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Do_Not_Project_NET7_0.md @@ -0,0 +1,22 @@ +# Do_Not_Project + +## SQL + +```text +SELECT b."Id", b."DisplayName", b."Name", b."Details_Country_Name" +FROM "Brands" AS b +WHERE b."Id" = 1 +``` + +## Result + +```json +{ + "data": { + "brandByIdNoProjection": { + "name": "Brand0" + } + } +} +``` + diff --git a/src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Force_A_Branch_NET7_0.md b/src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Force_A_Branch_NET7_0.md new file mode 100644 index 00000000000..293c0b0bf66 --- /dev/null +++ b/src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Force_A_Branch_NET7_0.md @@ -0,0 +1,36 @@ +# Force_A_Branch + +## SQL + +```text +SELECT p."Name", b."Name", p."Id" +FROM "Products" AS p +INNER JOIN "Brands" AS b ON p."BrandId" = b."Id" +WHERE p."Id" = 1 +SELECT p."Id", b."Id" +FROM "Products" AS p +INNER JOIN "Brands" AS b ON p."BrandId" = b."Id" +WHERE p."Id" = 1 +``` + +## Result + +```json +{ + "data": { + "a": { + "name": "Product 0-0", + "brand": { + "name": "Brand0" + } + }, + "b": { + "id": 1, + "brand": { + "id": 1 + } + } + } +} +``` + diff --git a/src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Manual_Include_Of_Brand_NET7_0.md b/src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Manual_Include_Of_Brand_NET7_0.md new file mode 100644 index 00000000000..48f7489e105 --- /dev/null +++ b/src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Manual_Include_Of_Brand_NET7_0.md @@ -0,0 +1,23 @@ +# Manual_Include_Of_Brand + +## SQL + +```text +SELECT p."Name", b."Id", b."DisplayName", b."Name", b."Details_Country_Name", p."Id" +FROM "Products" AS p +INNER JOIN "Brands" AS b ON p."BrandId" = b."Id" +WHERE p."Id" = 1 +``` + +## Result + +```json +{ + "data": { + "productByIdWithBrand": { + "name": "Product 0-0" + } + } +} +``` + diff --git a/src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Product_With_Name_And_Brand_With_Name_NET7_0.md b/src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Product_With_Name_And_Brand_With_Name_NET7_0.md new file mode 100644 index 00000000000..b4823d43c47 --- /dev/null +++ b/src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Product_With_Name_And_Brand_With_Name_NET7_0.md @@ -0,0 +1,26 @@ +# Product_With_Name_And_Brand_With_Name + +## SQL + +```text +SELECT p."Name", b."Name", p."Id" +FROM "Products" AS p +INNER JOIN "Brands" AS b ON p."BrandId" = b."Id" +WHERE p."Id" = 1 +``` + +## Result + +```json +{ + "data": { + "productById": { + "name": "Product 0-0", + "brand": { + "name": "Brand0" + } + } + } +} +``` + diff --git a/src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Project_And_Do_Not_Project_NET7_0.md b/src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Project_And_Do_Not_Project_NET7_0.md new file mode 100644 index 00000000000..19c433f7831 --- /dev/null +++ b/src/HotChocolate/Core/test/Execution.Tests/Projections/__snapshots__/ProjectableDataLoaderTests.Project_And_Do_Not_Project_NET7_0.md @@ -0,0 +1,28 @@ +# Project_And_Do_Not_Project + +## SQL + +```text +SELECT b."Id", b."DisplayName", b."Name", b."Details_Country_Name" +FROM "Brands" AS b +WHERE b."Id" = 1 +SELECT b."Name", b."Id" +FROM "Brands" AS b +WHERE b."Id" = 1 +``` + +## Result + +```json +{ + "data": { + "brandByIdNoProjection": { + "name": "Brand0" + }, + "brandById": { + "name": "Brand0" + } + } +} +``` + diff --git a/src/HotChocolate/Core/test/Types.Analyzers.Tests/DataLoaderTests.cs b/src/HotChocolate/Core/test/Types.Analyzers.Tests/DataLoaderTests.cs index 4478aac5198..39fa67c25ca 100644 --- a/src/HotChocolate/Core/test/Types.Analyzers.Tests/DataLoaderTests.cs +++ b/src/HotChocolate/Core/test/Types.Analyzers.Tests/DataLoaderTests.cs @@ -333,4 +333,29 @@ public class Entity } """).MatchMarkdownAsync(); } + + [Fact] + public async Task GenerateSource_BatchDataLoader_With_PagingArguments_MatchesSnapshot() + { + await TestHelper.GetGeneratedSourceSnapshot( + """ + using System.Collections.Generic; + using System.Threading; + using System.Threading.Tasks; + using HotChocolate; + using GreenDonut; + + namespace TestNamespace; + + internal static class TestClass + { + [DataLoader] + public static Task> GetEntityByIdAsync( + IReadOnlyList entityIds, + HotChocolate.Pagination.PagingArguments pagingArgs, + CancellationToken cancellationToken) + => default!; + } + """).MatchMarkdownAsync(); + } } diff --git a/src/HotChocolate/Core/test/Types.Analyzers.Tests/TestHelper.cs b/src/HotChocolate/Core/test/Types.Analyzers.Tests/TestHelper.cs index a50415c23ae..fa2d79153ec 100644 --- a/src/HotChocolate/Core/test/Types.Analyzers.Tests/TestHelper.cs +++ b/src/HotChocolate/Core/test/Types.Analyzers.Tests/TestHelper.cs @@ -7,6 +7,7 @@ using Basic.Reference.Assemblies; using CookieCrumble; using GreenDonut; +using HotChocolate.Pagination; using HotChocolate.Types.Analyzers; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; @@ -30,6 +31,9 @@ public static Snapshot GetGeneratedSourceSnapshot([StringSyntax("csharp")] strin // HotChocolate.Abstractions MetadataReference.CreateFromFile(typeof(ParentAttribute).Assembly.Location), + // HotChocolate.Pagination.Primitives + MetadataReference.CreateFromFile(typeof(PagingArguments).Assembly.Location), + // GreenDonut MetadataReference.CreateFromFile(typeof(DataLoaderAttribute).Assembly.Location) ]; diff --git a/src/HotChocolate/Core/test/Types.Analyzers.Tests/Types/DataLoaders.cs b/src/HotChocolate/Core/test/Types.Analyzers.Tests/Types/DataLoaders.cs index b6b7abcc07b..a1835731951 100644 --- a/src/HotChocolate/Core/test/Types.Analyzers.Tests/Types/DataLoaders.cs +++ b/src/HotChocolate/Core/test/Types.Analyzers.Tests/Types/DataLoaders.cs @@ -1,5 +1,6 @@ using GreenDonut; using GreenDonut.Projections; +using HotChocolate.Pagination; namespace HotChocolate.Types; @@ -64,7 +65,6 @@ public static async Task> GetSomeInfoWithServiceAndStat CancellationToken ct = default) => await Task.FromResult(keys.ToDictionary(k => k, k => k + " - some info")); -#if NET8_0_OR_GREATER [DataLoader] public static async Task> GetAuthorById( IReadOnlyList keys, @@ -72,5 +72,12 @@ public static async Task> GetAuthorById( ISelectorBuilder selector, CancellationToken ct) => await Task.FromResult(query.Select(selector, t => t.Id).ToDictionary(t => t.Id)); -#endif + + [DataLoader] + public static async Task> GetAuthorWithPagingById( + IReadOnlyList keys, + IQueryable query, + PagingArguments paging, + CancellationToken ct) + => await Task.FromResult(query.ToDictionary(t => t.Id)); } diff --git a/src/HotChocolate/Core/test/Types.Analyzers.Tests/__snapshots__/DataLoaderTests.GenerateSource_BatchDataLoader_With_PagingArguments_MatchesSnapshot.md b/src/HotChocolate/Core/test/Types.Analyzers.Tests/__snapshots__/DataLoaderTests.GenerateSource_BatchDataLoader_With_PagingArguments_MatchesSnapshot.md new file mode 100644 index 00000000000..6d693b13bde --- /dev/null +++ b/src/HotChocolate/Core/test/Types.Analyzers.Tests/__snapshots__/DataLoaderTests.GenerateSource_BatchDataLoader_With_PagingArguments_MatchesSnapshot.md @@ -0,0 +1,101 @@ +# GenerateSource_BatchDataLoader_With_PagingArguments_MatchesSnapshot + +## GreenDonutDataLoader.735550c.g.cs + +```csharp +// + +#nullable enable +#pragma warning disable + +using System; +using System.Runtime.CompilerServices; +using Microsoft.Extensions.DependencyInjection; +using GreenDonut; + +namespace TestNamespace +{ + public interface IEntityByIdDataLoader + : global::GreenDonut.IDataLoader + { + } + + public sealed class EntityByIdDataLoader + : global::GreenDonut.DataLoaderBase + , IEntityByIdDataLoader + { + private readonly global::System.IServiceProvider _services; + + public EntityByIdDataLoader( + global::System.IServiceProvider services, + global::GreenDonut.IBatchScheduler batchScheduler, + global::GreenDonut.DataLoaderOptions options) + : base(batchScheduler, options) + { + _services = services ?? + throw new global::System.ArgumentNullException(nameof(services)); + } + + protected override async global::System.Threading.Tasks.ValueTask FetchAsync( + global::System.Collections.Generic.IReadOnlyList keys, + global::System.Memory> results, + global::GreenDonut.DataLoaderFetchContext context, + global::System.Threading.CancellationToken ct) + { + var p1 = context.GetRequiredState("HotChocolate.Pagination.PagingArguments"); + var temp = await TestNamespace.TestClass.GetEntityByIdAsync(keys, p1, ct).ConfigureAwait(false); + CopyResults(keys, results.Span, temp); + } + + private void CopyResults( + global::System.Collections.Generic.IReadOnlyList keys, + global::System.Span> results, + global::System.Collections.Generic.IDictionary resultMap) + { + for (var i = 0; i < keys.Count; i++) + { + var key = keys[i]; + if (resultMap.TryGetValue(key, out var value)) + { + results[i] = global::GreenDonut.Result.Resolve(value); + } + else + { + results[i] = global::GreenDonut.Result.Resolve(default(string)); + } + } + } + } +} + + +``` + +## HotChocolateTypeModule.735550c.g.cs + +```csharp +// + +#nullable enable +#pragma warning disable + +using System; +using System.Runtime.CompilerServices; +using HotChocolate; +using HotChocolate.Types; +using HotChocolate.Execution.Configuration; + +namespace Microsoft.Extensions.DependencyInjection +{ + public static partial class TestsTypesRequestExecutorBuilderExtensions + { + public static IRequestExecutorBuilder AddTestsTypes(this IRequestExecutorBuilder builder) + { + builder.AddDataLoader(); + return builder; + } + } +} + +``` + diff --git a/src/HotChocolate/Pagination/HotChocolate.Pagination.sln b/src/HotChocolate/Pagination/HotChocolate.Pagination.sln index 1ebe642c322..8b3f14fc820 100644 --- a/src/HotChocolate/Pagination/HotChocolate.Pagination.sln +++ b/src/HotChocolate/Pagination/HotChocolate.Pagination.sln @@ -17,6 +17,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HotChocolate.Pagination.Ent EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HotChocolate.Pagination.Primitives", "src\Pagination.Primitives\HotChocolate.Pagination.Primitives.csproj", "{E9526D22-440D-40CF-B71D-FF70E5E773C2}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HotChocolate.Pagination.Batching", "src\Pagination.Batching\HotChocolate.Pagination.Batching.csproj", "{94DD5FC2-E034-4B77-A985-5F6FD63CC116}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -46,6 +48,10 @@ Global {E9526D22-440D-40CF-B71D-FF70E5E773C2}.Debug|Any CPU.Build.0 = Debug|Any CPU {E9526D22-440D-40CF-B71D-FF70E5E773C2}.Release|Any CPU.ActiveCfg = Release|Any CPU {E9526D22-440D-40CF-B71D-FF70E5E773C2}.Release|Any CPU.Build.0 = Release|Any CPU + {94DD5FC2-E034-4B77-A985-5F6FD63CC116}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {94DD5FC2-E034-4B77-A985-5F6FD63CC116}.Debug|Any CPU.Build.0 = Debug|Any CPU + {94DD5FC2-E034-4B77-A985-5F6FD63CC116}.Release|Any CPU.ActiveCfg = Release|Any CPU + {94DD5FC2-E034-4B77-A985-5F6FD63CC116}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {A265F87B-7602-4BD3-A253-E0C1B44F4C0F} = {C4F118E6-3F9B-419A-A61F-606487AA699B} @@ -53,5 +59,6 @@ Global {AB11480D-43B4-4032-8EC3-45F987D179D8} = {C4F118E6-3F9B-419A-A61F-606487AA699B} {C28F65B0-B87A-443C-B91D-728AD402947B} = {0663553C-7D78-496E-860A-2CC4EEED211C} {E9526D22-440D-40CF-B71D-FF70E5E773C2} = {C4F118E6-3F9B-419A-A61F-606487AA699B} + {94DD5FC2-E034-4B77-A985-5F6FD63CC116} = {C4F118E6-3F9B-419A-A61F-606487AA699B} EndGlobalSection EndGlobal diff --git a/src/HotChocolate/Pagination/src/Pagination.Batching/Extensions/HotChocolatePaginationBatchingDataLoaderExtensions.cs b/src/HotChocolate/Pagination/src/Pagination.Batching/Extensions/HotChocolatePaginationBatchingDataLoaderExtensions.cs new file mode 100644 index 00000000000..297d05e7789 --- /dev/null +++ b/src/HotChocolate/Pagination/src/Pagination.Batching/Extensions/HotChocolatePaginationBatchingDataLoaderExtensions.cs @@ -0,0 +1,115 @@ +using System.Diagnostics.CodeAnalysis; +using System.Linq.Expressions; +using System.Text; +using GreenDonut.Projections; +using HotChocolate.Pagination; + +namespace GreenDonut; + +/// +/// Provides extension methods to pass a pagination context to a DataLoader. +/// +public static class HotChocolatePaginationBatchingDataLoaderExtensions +{ + /// + /// Branches a DataLoader with the provided . + /// + /// + /// The DataLoader that shall be branched. + /// + /// + /// The paging arguments that shall be exist as state in the branched DataLoader. + /// + /// + /// The key type of the DataLoader. + /// + /// + /// The value type of the DataLoader. + /// + /// + /// Returns a branched DataLoader with the provided . + /// + /// + /// Throws if the is null. + /// + public static IPagingDataLoader WithPagingArguments( + this IDataLoader dataLoader, + PagingArguments pagingArguments) + where TKey : notnull + { + if (dataLoader is null) + { + throw new ArgumentNullException(nameof(dataLoader)); + } + + var branchKey = CreateBranchKey(pagingArguments); + return (IPagingDataLoader)dataLoader.Branch(branchKey, CreatePagingDataLoader, pagingArguments); + + static IDataLoader CreatePagingDataLoader( + string branchKey, + IDataLoader root, + PagingArguments pagingArguments) + { + var branch = new PagingDataLoader( + (DataLoaderBase)root, + branchKey); + branch.SetState(pagingArguments); + return branch; + } + } + + /// + /// Adds a projection as state to the DataLoader. + /// + /// + /// The DataLoader. + /// + /// + /// The projection that shall be added as state to the DataLoader. + /// + /// + /// The key type of the DataLoader. + /// + /// + /// The value type of the DataLoader. + /// + /// + /// Returns the DataLoader with the added projection. + /// + /// + /// Throws if the is null. + /// +#if NET8_0_OR_GREATER + [Experimental(Experiments.Projections)] +#endif + public static IPagingDataLoader Select( + this IPagingDataLoader dataLoader, + Expression> selector) + where TKey : notnull + { + if (dataLoader is null) + { + throw new ArgumentNullException(nameof(dataLoader)); + } + + if (selector is null) + { + throw new ArgumentNullException(nameof(selector)); + } + + var builder = dataLoader.GetOrSetState(_ => new DefaultSelectorBuilder()); + builder.Add(selector); + return dataLoader; + } + + private static string CreateBranchKey( + PagingArguments pagingArguments) + { + var key = new StringBuilder(); + key.Append(pagingArguments.First); + key.Append(pagingArguments.After); + key.Append(pagingArguments.Last); + key.Append(pagingArguments.Before); + return key.ToString(); + } +} diff --git a/src/HotChocolate/Pagination/src/Pagination.Batching/Extensions/HotChocolatePaginationBatchingDataLoaderFetchContext.cs b/src/HotChocolate/Pagination/src/Pagination.Batching/Extensions/HotChocolatePaginationBatchingDataLoaderFetchContext.cs new file mode 100644 index 00000000000..51ef6c03e8f --- /dev/null +++ b/src/HotChocolate/Pagination/src/Pagination.Batching/Extensions/HotChocolatePaginationBatchingDataLoaderFetchContext.cs @@ -0,0 +1,24 @@ +using HotChocolate.Pagination; + +namespace GreenDonut; + +/// +/// Provides extension method to the for pagination. +/// +public static class HotChocolatePaginationBatchingDataLoaderFetchContext +{ + /// + /// Gets the from the DataLoader fetch context. + /// + /// + /// The DataLoader fetch context. + /// + /// + /// The value type of the DataLoader. + /// + /// + /// Returns the from the DataLoader fetch context. + /// + public static PagingArguments GetPagingArguments(this DataLoaderFetchContext context) + => context.GetRequiredState(); +} diff --git a/src/HotChocolate/Pagination/src/Pagination.Batching/HotChocolate.Pagination.Batching.csproj b/src/HotChocolate/Pagination/src/Pagination.Batching/HotChocolate.Pagination.Batching.csproj new file mode 100644 index 00000000000..abc95b18a92 --- /dev/null +++ b/src/HotChocolate/Pagination/src/Pagination.Batching/HotChocolate.Pagination.Batching.csproj @@ -0,0 +1,15 @@ + + + + HotChocolate.Pagination.Batching + HotChocolate.Pagination.Batching + HotChocolate.Pagination + Contains serialization for paging keys and general helpers. + + + + + + + + diff --git a/src/HotChocolate/Pagination/src/Pagination.Batching/IPagingDataLoader.cs b/src/HotChocolate/Pagination/src/Pagination.Batching/IPagingDataLoader.cs new file mode 100644 index 00000000000..67c50d80053 --- /dev/null +++ b/src/HotChocolate/Pagination/src/Pagination.Batching/IPagingDataLoader.cs @@ -0,0 +1,28 @@ +using GreenDonut; + +namespace HotChocolate.Pagination; + +/// +/// A paging DataLoader is a version of a DataLoader that +/// branches per paging arguments. +/// +/// +/// The type of the key. +/// +/// +/// The type of the value. +/// +public interface IPagingDataLoader + : IDataLoader + where TKey : notnull +{ + /// + /// Gets the root DataLoader instance from which this instance was branched off. + /// + IDataLoader Root { get; } + + /// + /// Gets the paging arguments for this DataLoader. + /// + PagingArguments PagingArguments { get; } +} diff --git a/src/HotChocolate/Pagination/src/Pagination.Batching/PagingDataLoader.cs b/src/HotChocolate/Pagination/src/Pagination.Batching/PagingDataLoader.cs new file mode 100644 index 00000000000..90515824148 --- /dev/null +++ b/src/HotChocolate/Pagination/src/Pagination.Batching/PagingDataLoader.cs @@ -0,0 +1,39 @@ +using GreenDonut; +using GreenDonut.Internals; + +namespace HotChocolate.Pagination; + +internal sealed class PagingDataLoader + : DataLoaderBase + , IPagingDataLoader + where TKey : notnull +{ + private readonly DataLoaderBase _root; + + public PagingDataLoader( + DataLoaderBase root, + string pagingKey) + : base(DataLoaderHelper.GetBatchScheduler(root), DataLoaderHelper.GetOptions(root)) + { + _root = root; + CacheKeyType = $"{DataLoaderHelper.GetCacheKeyType(root)}:{pagingKey}"; + } + + public IDataLoader Root => _root; + + public PagingArguments PagingArguments + => (PagingArguments)ContextData[typeof(PagingArguments).FullName!]!; + + protected internal override string CacheKeyType { get; } + + protected override bool AllowCachePropagation => false; + + protected override bool AllowBranching => false; + + protected internal override ValueTask FetchAsync( + IReadOnlyList keys, + Memory> results, + DataLoaderFetchContext context, + CancellationToken cancellationToken) + => DataLoaderHelper.FetchAsync(_root, keys, results, context, cancellationToken); +} diff --git a/src/HotChocolate/Pagination/src/Pagination.Core/Expressions/ExpressionHelpers.cs b/src/HotChocolate/Pagination/src/Pagination.Core/Expressions/ExpressionHelpers.cs index 33e87a3f0b4..26ac834d78e 100644 --- a/src/HotChocolate/Pagination/src/Pagination.Core/Expressions/ExpressionHelpers.cs +++ b/src/HotChocolate/Pagination/src/Pagination.Core/Expressions/ExpressionHelpers.cs @@ -1,6 +1,7 @@ using System.Collections.Concurrent; using System.Linq.Expressions; using System.Reflection; +using System.Runtime.InteropServices; namespace HotChocolate.Pagination.Expressions; @@ -11,6 +12,7 @@ public static class ExpressionHelpers { private static readonly MethodInfo _createAndConvert = typeof(ExpressionHelpers) .GetMethod(nameof(CreateAndConvertParameter), BindingFlags.NonPublic | BindingFlags.Static)!; + private static readonly ConcurrentDictionary> _cachedConverters = new(); /// @@ -38,31 +40,242 @@ public static class ExpressionHelpers /// If the number of keys does not match the number of values. /// public static Expression> BuildWhereExpression( - CursorKey[] keys, - object?[] cursor, + ReadOnlySpan keys, + ReadOnlySpan cursor, bool forward) { - if (keys == null) + if (keys.Length == 0) { - throw new ArgumentNullException(nameof(keys)); + throw new ArgumentException("At least one key must be specified.", nameof(keys)); } - if (cursor == null) + if (keys.Length != cursor.Length) + { + throw new ArgumentException("The number of keys must match the number of values.", nameof(cursor)); + } + + var cursorExpr = new Expression[cursor.Length]; + for (var i = 0; i < cursor.Length; i++) { - throw new ArgumentNullException(nameof(cursor)); + cursorExpr[i] = CreateParameter(cursor[i], keys[i].Expression.ReturnType); } + var handled = new List(); + Expression? expression = null; + + var parameter = Expression.Parameter(typeof(T), "t"); + var zero = Expression.Constant(0); + + for (var i = 0; i < keys.Length; i++) + { + var key = keys[i]; + Expression? current = null; + Expression keyExpr; + + for (var j = 0; j < handled.Count; j++) + { + var handledKey = handled[j]; + + keyExpr = + Expression.Equal( + Expression.Call( + ReplaceParameter(handledKey.Expression, parameter), + handledKey.CompareMethod, + cursorExpr[j]), + zero); + + current = current is null + ? keyExpr + : Expression.AndAlso(current, keyExpr); + } + + var greaterThan = forward + ? key.Direction is CursorKeyDirection.Ascending + : key.Direction is CursorKeyDirection.Descending; + + keyExpr = + greaterThan + ? Expression.GreaterThan( + Expression.Call( + ReplaceParameter(key.Expression, parameter), + key.CompareMethod, + cursorExpr[i]), + zero) + : Expression.LessThan( + Expression.Call( + ReplaceParameter(key.Expression, parameter), + key.CompareMethod, + cursorExpr[i]), + zero); + + current = current is null + ? keyExpr + : Expression.AndAlso(current, keyExpr); + expression = expression is null + ? current + : Expression.OrElse(expression, current); + handled.Add(key); + } + + return Expression.Lambda>(expression!, parameter); + } + + /// + /// Build the select expression for a batch paging expression that uses grouping. + /// + /// + /// The paging arguments. + /// + /// + /// The key definitions that represent the cursor. + /// + /// + /// The order expressions that are used to sort the dataset. + /// + /// + /// The order methods that are used to sort the dataset. + /// + /// + /// Defines how the dataset is sorted. + /// + /// + /// The number of items that are requested. + /// + /// + /// The key type. + /// + /// + /// The value type. + /// + /// + /// + /// If the number of keys is less than one or + /// the number of order expressions does not match the number of order methods. + /// + public static Expression, Group>> BuildBatchSelectExpression( + PagingArguments arguments, + ReadOnlySpan keys, + ReadOnlySpan orderExpressions, + ReadOnlySpan orderMethods, + bool forward, + ref int requestedCount) + { if (keys.Length == 0) { - throw new ArgumentException("At least one key must be specified.", nameof(keys)); + throw new ArgumentException( + "At least one key must be specified.", + nameof(keys)); } - if (keys.Length != cursor.Length) + if (orderExpressions.Length != orderMethods.Length) { - throw new ArgumentException("The number of keys must match the number of values.", nameof(cursor)); + throw new ArgumentException( + "The number of order expressions must match the number of order methods.", + nameof(orderExpressions)); + } + + var group = Expression.Parameter(typeof(IGrouping), "g"); + var groupKey = Expression.Property(group, "Key"); + Expression source = group; + + for (var i = 0; i < orderExpressions.Length; i++) + { + var methodName = orderMethods[i]; + var orderExpression = orderExpressions[i]; + + if (!forward) + { + methodName = ReverseOrder(methodName); + } + + var delegateType = typeof(Func<,>).MakeGenericType(typeof(TV), orderExpression.Body.Type); + var typedOrderExpression = Expression.Lambda(delegateType, orderExpression.Body, orderExpression.Parameters); + + var method = GetEnumerableMethod(methodName, typeof(TV), typedOrderExpression); + + source = Expression.Call( + method, + source, + typedOrderExpression); + } + + if (arguments.After is not null) + { + var cursor = CursorParser.Parse(arguments.After, keys); + source = BuildBatchWhereExpression(source, keys, cursor, forward); + } + + if (arguments.Before is not null) + { + var cursor = CursorParser.Parse(arguments.Before, keys); + source = BuildBatchWhereExpression(source, keys, cursor, forward); + } + + if (arguments.First is not null) + { + source = Expression.Call( + typeof(Enumerable), + "Take", + [typeof(TV)], + source, + Expression.Constant(arguments.First.Value + 1)); + requestedCount = arguments.First.Value; } + if (arguments.Last is not null) + { + source = Expression.Call( + typeof(Enumerable), + "Take", + [typeof(TV)], + source, + Expression.Constant(arguments.Last.Value + 1)); + requestedCount = arguments.Last.Value; + } + + source = Expression.Call( + typeof(Enumerable), + "ToList", + [typeof(TV)], + source); + + var groupType = typeof(Group); + var bindings = new MemberBinding[] + { + Expression.Bind(groupType.GetProperty(nameof(Group.Key))!, groupKey), + Expression.Bind(groupType.GetProperty(nameof(Group.Items))!, source) + }; + + var createGroup = Expression.MemberInit(Expression.New(groupType), bindings); + return Expression.Lambda, Group>>(createGroup, group); + + static string ReverseOrder(string method) + => method switch + { + nameof(Queryable.OrderBy) => nameof(Queryable.OrderByDescending), + nameof(Queryable.OrderByDescending) => nameof(Queryable.OrderBy), + nameof(Queryable.ThenBy) => nameof(Queryable.ThenByDescending), + nameof(Queryable.ThenByDescending) => nameof(Queryable.ThenBy), + _ => method + }; + + static MethodInfo GetEnumerableMethod(string methodName, Type elementType, LambdaExpression keySelector) + { + return typeof(Enumerable) + .GetMethods(BindingFlags.Static | BindingFlags.Public) + .First(m => m.Name == methodName && m.GetParameters().Length == 2) + .MakeGenericMethod(elementType, keySelector.Body.Type); + } + } + + private static MethodCallExpression BuildBatchWhereExpression( + Expression enumerable, + ReadOnlySpan keys, + object?[] cursor, + bool forward) + { var cursorExpr = new Expression[cursor.Length]; + for (var i = 0; i < cursor.Length; i++) { cursorExpr[i] = CreateParameter(cursor[i], keys[i].Expression.ReturnType); @@ -125,7 +338,30 @@ public static Expression> BuildWhereExpression( handled.Add(key); } - return Expression.Lambda>(expression!, parameter); + return Expression.Call( + typeof(Enumerable), + "Where", + [typeof(T)], + enumerable, + Expression.Lambda>(expression!, parameter)); + } + + /// + /// Extracts and removes the orderBy and thenBy expressions from the given expression tree. + /// + /// + /// + /// + public static OrderRewriterResult ExtractAndRemoveOrder(Expression expression) + { + if(expression is null) + { + throw new ArgumentNullException(nameof(expression)); + } + + var rewriter = new OrderByRemovalRewriter(); + var (result, orderExpressions, orderMethods) = rewriter.Rewrite(expression); + return new OrderRewriterResult(result, orderExpressions, orderMethods); } private static Expression CreateParameter(object? value, Type type) @@ -163,4 +399,80 @@ protected override Expression VisitParameter(ParameterExpression node) return node == parameter ? replacement : base.VisitParameter(node); } } + + public class Group + { + public TKey Key { get; set; } = default!; + + public List Items { get; set; } = default!; + } + + public readonly struct OrderRewriterResult( + Expression expression, + List orderExpressions, + List orderMethods) + { + public Expression Expression => expression; + + public ReadOnlySpan OrderExpressions => CollectionsMarshal.AsSpan(orderExpressions); + + public ReadOnlySpan OrderMethods => CollectionsMarshal.AsSpan(orderMethods); + } + + private sealed class OrderByRemovalRewriter : ExpressionVisitor + { + private readonly List _orderExpressions = new(); + private readonly List _orderMethods = new(); + private bool _insideSelectProjection; + + public (Expression, List, List) Rewrite(Expression expression) + { + var result = Visit(expression); + + _orderExpressions.Reverse(); + _orderMethods.Reverse(); + + return (result, _orderExpressions, _orderMethods); + } + + protected override Expression VisitMethodCall(MethodCallExpression node) + { + // we are not interested in nested order by calls + if (node.Method.DeclaringType == typeof(Queryable) && node.Method.Name == nameof(Queryable.Select)) + { + var previousState = _insideSelectProjection; + _insideSelectProjection = true; + var result = base.VisitMethodCall(node); + _insideSelectProjection = previousState; + return result; + } + + if (node.Method.DeclaringType == typeof(Queryable) + && (node.Method.Name == nameof(Queryable.OrderBy) + || node.Method.Name == nameof(Queryable.OrderByDescending) + || node.Method.Name == nameof(Queryable.ThenBy) + || node.Method.Name == nameof(Queryable.ThenByDescending))) + { + if (!_insideSelectProjection) + { + var lambda = (LambdaExpression)StripQuotes(node.Arguments[1]); + _orderExpressions.Add(lambda); + _orderMethods.Add(node.Method.Name); + return Visit(node.Arguments[0]); + } + } + + return base.VisitMethodCall(node); + } + + private static Expression StripQuotes(Expression e) + { + while (e.NodeType == ExpressionType.Quote) + { + e = ((UnaryExpression)e).Operand; + } + + return e; + } + } } diff --git a/src/HotChocolate/Pagination/src/Pagination.Core/HotChocolate.Pagination.Core.csproj b/src/HotChocolate/Pagination/src/Pagination.Core/HotChocolate.Pagination.Core.csproj index fabc413633e..f2009b4a3c8 100644 --- a/src/HotChocolate/Pagination/src/Pagination.Core/HotChocolate.Pagination.Core.csproj +++ b/src/HotChocolate/Pagination/src/Pagination.Core/HotChocolate.Pagination.Core.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/HotChocolate/Pagination/src/Pagination.EntityFramework/Expressions/BatchQueryRewriter.cs b/src/HotChocolate/Pagination/src/Pagination.EntityFramework/Expressions/BatchQueryRewriter.cs deleted file mode 100644 index c36efd4aa80..00000000000 --- a/src/HotChocolate/Pagination/src/Pagination.EntityFramework/Expressions/BatchQueryRewriter.cs +++ /dev/null @@ -1,173 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Linq.Expressions; -using System.Reflection; - -namespace HotChocolate.Pagination.Expressions; - -internal sealed class BatchQueryRewriter(PagingArguments arguments) : ExpressionVisitor -{ - private static readonly Type _enumerable = typeof(Enumerable); - private static readonly Type _extensions = typeof(EntityFrameworkQueryableExtensions); - private PropertyInfo? _resultProperty; - private CursorKey[]? _keys; - - public PropertyInfo ResultProperty => _resultProperty ?? throw new InvalidOperationException(); - - public CursorKey[] Keys => _keys ?? throw new InvalidOperationException(); - - protected override Expression VisitExtension(Expression node) - => node.CanReduce - ? base.VisitExtension(node) - : node; - - protected override Expression VisitMethodCall(MethodCallExpression node) - { - if (IsInclude(node) && TryExtractProperty(node, out var property) && _resultProperty is null) - { - _resultProperty = property; - var newIncludeExpression = RewriteInclude(node, property); - return base.VisitMethodCall(newIncludeExpression); - } - - return base.VisitMethodCall(node); - } - - private MethodCallExpression RewriteInclude(MethodCallExpression node, PropertyInfo property) - { - var forward = arguments.Last is null; - - var entityType = node.Arguments[0].Type.GetGenericArguments()[0]; - var includeType = property.PropertyType.GetGenericArguments()[0]; - var lambda = (LambdaExpression)((UnaryExpression)node.Arguments[1]).Operand; - - var parser = new CursorKeyParser(); - parser.Visit(lambda); - var keys = _keys = parser.Keys.ToArray(); - - var pagingExpr = ApplyPaging(lambda.Body, arguments, keys, forward); - var newLambda = Expression.Lambda(pagingExpr, lambda.Parameters); - return Expression.Call(null, Include(), node.Arguments[0], Expression.Constant(newLambda)); - - MethodInfo Include() - => _extensions - .GetMethods(BindingFlags.Public | BindingFlags.Static) - .First(t => t.Name.Equals("Include") && t.GetGenericArguments().Length == 2) - .MakeGenericMethod(entityType, typeof(IEnumerable<>).MakeGenericType(includeType)); - } - - private static Expression ApplyPaging( - Expression enumerable, - PagingArguments pagingArgs, - CursorKey[] keys, - bool forward) - { - MethodInfo? where = null; - MethodInfo? take = null; - - if (pagingArgs.After is not null) - { - var cursor = CursorParser.Parse(pagingArgs.After, keys); - enumerable = Expression.Call( - null, - Where(), - enumerable, - ExpressionHelpers.BuildWhereExpression(keys, cursor, forward)); - } - - if (pagingArgs.Before is not null) - { - var cursor = CursorParser.Parse(pagingArgs.Before, keys); - enumerable = Expression.Call( - null, - Where(), - enumerable, - ExpressionHelpers.BuildWhereExpression(keys, cursor, forward)); - } - - if (pagingArgs.First is not null) - { - var firstValue = pagingArgs.First + 1; - var first = Expression.Constant(firstValue); - enumerable = Expression.Call(null, Take(), enumerable, first); - } - - if (pagingArgs.Last is not null) - { - var lastValue = pagingArgs.Last + 1; - var last = Expression.Constant(lastValue); - enumerable = Expression.Call(null, Take(), enumerable, last); - } - - return enumerable; - - MethodInfo Where() - => where ??= _enumerable - .GetMethods(BindingFlags.Public | BindingFlags.Static) - .First(t => t.Name.Equals("Where") && t.GetGenericArguments().Length == 1) - .MakeGenericMethod(typeof(T)); - - MethodInfo Take() - => take ??= typeof(Enumerable) - .GetMethods(BindingFlags.Public | BindingFlags.Static) - .First(t => t.Name.Equals("Take") && t.GetGenericArguments().Length == 1) - .MakeGenericMethod(typeof(T)); - } - - private static bool IsInclude(MethodCallExpression node) - => IsMethod(node, nameof(EntityFrameworkQueryableExtensions.Include)); - - private static bool IsMethod(MethodCallExpression node, string name) - => node.Method.DeclaringType == typeof(EntityFrameworkQueryableExtensions) && - node.Method.Name.Equals(name, StringComparison.Ordinal); - - private static bool TryExtractProperty( - MethodCallExpression node, - [NotNullWhen(true)] out PropertyInfo? property) - { - if (node.Arguments is [_, UnaryExpression { Operand: LambdaExpression l }]) - { - return TryExtractProperty1(l.Body, out property); - } - - property = null; - return false; - } - - private static bool TryExtractProperty1(Expression expression, out PropertyInfo? property) - { - property = null; - - switch (expression) - { - case MemberExpression memberExpression: - property = memberExpression.Member as PropertyInfo; - return property != null; - - case MethodCallExpression methodCallExpression: - { - if (methodCallExpression.Arguments.Count > 0) - { - var firstArgument = methodCallExpression.Arguments[0]; - - switch (firstArgument) - { - case MethodCallExpression: - return TryExtractProperty1(firstArgument, out property); - - case UnaryExpression unaryExpression: - return TryExtractProperty1(unaryExpression.Operand, out property); - - case MemberExpression: - return TryExtractProperty1(firstArgument, out property); - } - } - break; - } - - case UnaryExpression unaryExpression: - return TryExtractProperty1(unaryExpression.Operand, out property); - } - - return false; - } -} diff --git a/src/HotChocolate/Pagination/src/Pagination.EntityFramework/Extensions/PagingQueryableExtensions.cs b/src/HotChocolate/Pagination/src/Pagination.EntityFramework/Extensions/PagingQueryableExtensions.cs index b8f9ac8a9cb..8f3e7230f37 100644 --- a/src/HotChocolate/Pagination/src/Pagination.EntityFramework/Extensions/PagingQueryableExtensions.cs +++ b/src/HotChocolate/Pagination/src/Pagination.EntityFramework/Extensions/PagingQueryableExtensions.cs @@ -1,6 +1,6 @@ using System.Collections.Immutable; +using System.Linq.Expressions; using HotChocolate.Pagination.Expressions; -using Microsoft.EntityFrameworkCore.Query; using static HotChocolate.Pagination.Expressions.ExpressionHelpers; namespace HotChocolate.Pagination; @@ -37,7 +37,6 @@ public static async ValueTask> ToPageAsync( CancellationToken cancellationToken = default) => await source.ToPageAsync(arguments, includeTotalCount: false, cancellationToken); - /// /// Executes a query with paging and returns the selected page. /// @@ -183,36 +182,30 @@ public static async ValueTask> ToPageAsync( /// /// The cancellation token. /// - /// - /// The type of the items in the queryable. - /// /// /// The type of the parent key. /// - /// - /// The type of the property that is being paged. + /// + /// The type of the items in the queryable. /// - /// - /// Returns a dictionary of pages for each parent. - /// - /// - /// If the result is not a list or an enumerable. + /// + /// + /// If the queryable does not have any keys specified. /// - public static async ValueTask, Page>> ToBatchPageAsync( - this IIncludableQueryable> source, - Func keySelector, + public static async ValueTask>> ToBatchPageAsync( + this IQueryable source, + Expression> keySelector, PagingArguments arguments, CancellationToken cancellationToken = default) where TKey : notnull { - if (source == null) - { - throw new ArgumentNullException(nameof(source)); - } + var keys = ParseDataSetKeys(source); - if (keySelector == null) + if (keys.Length == 0) { - throw new ArgumentNullException(nameof(keySelector)); + throw new ArgumentException( + "In order to use cursor pagination, you must specify at least one key using the `OrderBy` method.", + nameof(source)); } if (arguments.Last is not null && arguments.First is not null) @@ -222,61 +215,52 @@ public static async ValueTask, Page>> ToBatc nameof(arguments)); } - var rewriter = new BatchQueryRewriter(arguments); - var expression = rewriter.Visit(source.Expression); - var list = await source.Provider.CreateQuery(expression).ToListAsync(cancellationToken); - var result = new Dictionary, Page>(); - var requestedItems = int.MaxValue; + // we need to move the ordering into the select expression we are constructing + // so that the groupBy will not remove it. The first thing we do here is to extract the order expressions + // and to create a new expression that will not contain it anymore. + var ordering = ExtractAndRemoveOrder(source.Expression); - if (arguments.First.HasValue) - { - requestedItems = arguments.First.Value; - } - - if (arguments.Last.HasValue) - { - requestedItems = arguments.Last.Value; - } - - foreach (var group in list) + var forward = arguments.Last is null; + var requestedCount = int.MaxValue; + var selectExpression = + BuildBatchSelectExpression( + arguments, + keys, + ordering.OrderExpressions, + ordering.OrderMethods, + forward, + ref requestedCount); + var map = new Dictionary>(); + + // we apply our new expression here. + source = source.Provider.CreateQuery(ordering.Expression); + + await foreach (var item in source + .GroupBy(keySelector) + .Select(selectExpression) + .AsAsyncEnumerable() + .WithCancellation(cancellationToken) + .ConfigureAwait(false)) { - var key = new PageKey(keySelector(group), arguments); - var builder = ImmutableArray.CreateBuilder(); - - switch (rewriter.ResultProperty.GetValue(group)) + if (item.Items.Count == 0) { - case IReadOnlyList resultList: - builder.AddRange(resultList); - - // if we over-fetched we remove the last item. - if (requestedItems < builder.Count) - { - builder.RemoveAt(builder.Count - 1); - } - - result.Add(key, CreatePage(builder.ToImmutable(), arguments, rewriter.Keys, resultList.Count)); - break; - - case IEnumerable resultEnumerable: - builder.AddRange(resultEnumerable); - var fetchCount = builder.Count; - - // if we over-fetched we remove the last item. - if (requestedItems < fetchCount) - { - builder.RemoveAt(builder.Count - 1); - } + map.Add(item.Key, Page.Empty); + continue; + } - result.Add(key, CreatePage(builder.ToImmutable(), arguments, rewriter.Keys, fetchCount)); - break; + var itemCount = requestedCount > item.Items.Count ? item.Items.Count : requestedCount; + var builder = ImmutableArray.CreateBuilder(itemCount); - default: - throw new InvalidOperationException( - "The result must be a list or an enumerable."); + for (var i = 0; i < itemCount; i++) + { + builder.Add(item.Items[i]); } + + var page = CreatePage(builder.ToImmutable(), arguments, keys, item.Items.Count); + map.Add(item.Key, page); } - return result; + return map; } private static Page CreatePage( @@ -297,7 +281,7 @@ private static Page CreatePage( hasPrevious = true; } - // if we required the last 5 items of a dataset and overfetch by 1 + // if we required the last 5 items of a dataset and over-fetch by 1 // than we have a previous page. if (arguments.Last is not null && fetchCount > arguments.Last) { diff --git a/src/HotChocolate/Pagination/test/Pagination.EntityFramework.Tests/PagingHelperIntegrationTests.cs b/src/HotChocolate/Pagination/test/Pagination.EntityFramework.Tests/PagingHelperIntegrationTests.cs index 21451cf31d5..f1600ecf36c 100644 --- a/src/HotChocolate/Pagination/test/Pagination.EntityFramework.Tests/PagingHelperIntegrationTests.cs +++ b/src/HotChocolate/Pagination/test/Pagination.EntityFramework.Tests/PagingHelperIntegrationTests.cs @@ -1,5 +1,7 @@ using HotChocolate.Data.TestContext; using CookieCrumble; +using GreenDonut; +using GreenDonut.Projections; using HotChocolate.Execution; using HotChocolate.Types; using HotChocolate.Types.Pagination; @@ -387,6 +389,49 @@ public async Task GetDefaultPage_With_Deep_SecondPage() result.MatchMarkdownSnapshot(); } + [Fact] + public async Task Nested_Paging_First_2() + { + // Arrange + var connectionString = CreateConnectionString(); + await SeedAsync(connectionString); + + // Act + var result = await new ServiceCollection() + .AddScoped(_ => new CatalogContext(connectionString)) + .AddGraphQL() + .AddQueryType() + .AddTypeExtension(typeof(BrandExtensions)) + .AddPagingArguments() + .ModifyRequestOptions(o => o.IncludeExceptionDetails = true) + .ExecuteRequestAsync( + """ + { + brands(first: 2) { + edges { + cursor + } + nodes { + products(first: 2) { + nodes { + name + } + pageInfo { + hasNextPage + hasPreviousPage + startCursor + endCursor + } + } + } + } + } + """); + + // Assert + result.MatchMarkdownSnapshot(); + } + [Fact] public async Task Paging_Empty_PagingArgs() { @@ -539,37 +584,26 @@ public async Task BatchPaging_First_5() var pagingArgs = new PagingArguments { First = 2 }; - var results = await context.Brands - .Where(t => t.Id == 1 || t.Id == 2 || t.Id == 3) - .Include(t => t.Products.OrderBy(p => p.Id)) - .ToBatchPageAsync(k => k.Id, pagingArgs); + var results = await context.Products + .Where(t => t.BrandId == 1 || t.BrandId == 2 || t.BrandId == 3) + .OrderBy(p => p.Name) + .ThenBy(p => p.Id) + .ToBatchPageAsync(k => k.BrandId, pagingArgs); // Assert - var snapshot = new Snapshot(); - - foreach (var result in results) + var snapshot = Snapshot.Create(); + foreach (var page in results) { - var key = result.Key.Key; - foreach (var product in result.Value.Items) - { - product.Brand = null; - } - snapshot.Add( new { - result.Value.HasNextPage, - result.Value.HasPreviousPage, - First = result.Value.First?.Id, - FirstCursor = result.Value.First is not null ? result.Value.CreateCursor(result.Value.First) : null, - Last = result.Value.Last?.Id, - LastCursor = result.Value.Last is not null ? result.Value.CreateCursor(result.Value.Last) : null, - result.Value.Items + First = page.Value.CreateCursor(page.Value.First!), + Last = page.Value.CreateCursor(page.Value.Last!), + page.Value.Items }, - "Brand " + key); + name: page.Key.ToString()); } - - await snapshot.MatchMarkdownAsync(); + snapshot.MatchMarkdownSnapshot(); } [Fact] @@ -584,37 +618,25 @@ public async Task BatchPaging_Last_5() var pagingArgs = new PagingArguments { Last = 2 }; - var results = await context.Brands - .Where(t => t.Id == 1 || t.Id == 2 || t.Id == 3) - .Include(t => t.Products.OrderBy(p => p.Id)) - .ToBatchPageAsync(k => k.Id, pagingArgs); + var results = await context.Products + .Where(t => t.BrandId == 1 || t.BrandId == 2 || t.BrandId == 3) + .OrderBy(p => p.Id) + .ToBatchPageAsync(k => k.BrandId, pagingArgs); // Assert - var snapshot = new Snapshot(); - - foreach (var result in results) + var snapshot = Snapshot.Create(); + foreach (var page in results) { - var key = result.Key.Key; - foreach (var product in result.Value.Items) - { - product.Brand = null; - } - snapshot.Add( new { - result.Value.HasNextPage, - result.Value.HasPreviousPage, - First = result.Value.First?.Id, - FirstCursor = result.Value.First is not null ? result.Value.CreateCursor(result.Value.First) : null, - Last = result.Value.Last?.Id, - LastCursor = result.Value.Last is not null ? result.Value.CreateCursor(result.Value.Last) : null, - result.Value.Items + First = page.Value.CreateCursor(page.Value.First!), + Last = page.Value.CreateCursor(page.Value.Last!), + page.Value.Items }, - "Brand " + key); + name: page.Key.ToString()); } - - await snapshot.MatchMarkdownAsync(); + snapshot.MatchMarkdownSnapshot(); } private static async Task SeedAsync(string connectionString) @@ -709,4 +731,49 @@ public async Task> GetBrandsDeep( .ToPageAsync(arguments, cancellationToken: ct) .ToConnectionAsync(); } + + [ExtendObjectType] + public static class BrandExtensions + { + [UsePaging] + public static async Task> GetProducts( + [Parent] Brand brand, + ProductsByBrandDataLoader dataLoader, + PagingArguments arguments, + CancellationToken cancellationToken) + => await dataLoader + .WithPagingArguments(arguments) + .LoadAsync(brand.Id, cancellationToken) + .ToConnectionAsync(); + } + + public class ProductsByBrandDataLoader : StatefulBatchDataLoader> + { + private readonly IServiceProvider _services; + + public ProductsByBrandDataLoader( + IServiceProvider services, + IBatchScheduler batchScheduler, + DataLoaderOptions options) + : base(batchScheduler, options) + { + _services = services; + } + + protected override async Task>> LoadBatchAsync( + IReadOnlyList keys, + DataLoaderFetchContext> context, + CancellationToken cancellationToken) + { + var pagingArgs = context.GetPagingArguments(); + + await using var scope = _services.CreateAsyncScope(); + await using var catalogContext = scope.ServiceProvider.GetRequiredService(); + + return await catalogContext.Products + .Where(t => keys.Contains(t.BrandId)) + .OrderBy(t => t.Name).ThenBy(t => t.Id) + .ToBatchPageAsync(t => t.BrandId, pagingArgs, cancellationToken); + } + } } diff --git a/src/HotChocolate/Pagination/test/Pagination.EntityFramework.Tests/PagingHelperTests.cs b/src/HotChocolate/Pagination/test/Pagination.EntityFramework.Tests/PagingHelperTests.cs index e58ccbcc5dd..dbd46bb9e16 100644 --- a/src/HotChocolate/Pagination/test/Pagination.EntityFramework.Tests/PagingHelperTests.cs +++ b/src/HotChocolate/Pagination/test/Pagination.EntityFramework.Tests/PagingHelperTests.cs @@ -86,7 +86,9 @@ public async Task Fetch_Last_2_Items() // Act var arguments = new PagingArguments(last: 2); await using var context = new CatalogContext(connectionString); - var page = await context.Products.OrderBy(t => t.Name).ThenBy(t => t.Id) + var page = await context.Products + .OrderBy(t => t.Name) + .ThenBy(t => t.Id) .ToPageAsync(arguments); // Assert @@ -103,7 +105,9 @@ public async Task Fetch_Last_2_Items_Before_Last_Page() // .. get last page var arguments = new PagingArguments(last: 2); await using var context = new CatalogContext(connectionString); - var page = await context.Products.OrderBy(t => t.Name).ThenBy(t => t.Id) + var page = await context.Products + .OrderBy(t => t.Name) + .ThenBy(t => t.Id) .ToPageAsync(arguments); // Act @@ -122,14 +126,29 @@ public async Task Batch_Fetch_First_2_Items() await SeedAsync(connectionString); // Act + int[] brandIds = [1, 2, 3]; var arguments = new PagingArguments(2); await using var context = new CatalogContext(connectionString); - var page = await context.Brands - .Include(t => t.Products.OrderBy(p => p.Name).ThenBy(p => p.Id)) - .ToBatchPageAsync(t => t.Id, arguments); + var pages = await context.Products + .Where(t => brandIds.Contains(t.BrandId)) + .OrderBy(p => p.Name) + .ThenBy(p => p.Id) + .ToBatchPageAsync(t => t.BrandId, arguments); // Assert - page.MatchMarkdownSnapshot(); + var snapshot = Snapshot.Create(); + foreach (var page in pages) + { + snapshot.Add( + new + { + First = page.Value.CreateCursor(page.Value.First!), + Last = page.Value.CreateCursor(page.Value.Last!), + page.Value.Items + }, + name: page.Key.ToString()); + } + snapshot.MatchMarkdownSnapshot(); } [Fact] @@ -201,7 +220,9 @@ private static async Task SeedAsync(string connectionString) { var product = new Product { - Name = $"Product {i}-{j}", Type = type, Brand = brand, + Name = $"Product {i}-{j}", + Type = type, + Brand = brand, }; context.Products.Add(product); } diff --git a/src/HotChocolate/Pagination/test/Pagination.EntityFramework.Tests/__snapshots__/IntegrationPagingHelperTests.BatchPaging_First_5.md b/src/HotChocolate/Pagination/test/Pagination.EntityFramework.Tests/__snapshots__/IntegrationPagingHelperTests.BatchPaging_First_5.md index bdd4a48dd77..278a12936ef 100644 --- a/src/HotChocolate/Pagination/test/Pagination.EntityFramework.Tests/__snapshots__/IntegrationPagingHelperTests.BatchPaging_First_5.md +++ b/src/HotChocolate/Pagination/test/Pagination.EntityFramework.Tests/__snapshots__/IntegrationPagingHelperTests.BatchPaging_First_5.md @@ -1,15 +1,11 @@ # BatchPaging_First_5 -## Brand 1 +## 1 ```json { - "HasNextPage": true, - "HasPreviousPage": false, - "First": 1, - "FirstCursor": "MQ==", - "Last": 2, - "LastCursor": "Mg==", + "First": "UHJvZHVjdCAwLTA6MQ==", + "Last": "UHJvZHVjdCAwLTE6Mg==", "Items": [ { "Id": 1, @@ -45,16 +41,12 @@ } ``` -## Brand 2 +## 2 ```json { - "HasNextPage": true, - "HasPreviousPage": false, - "First": 101, - "FirstCursor": "MTAx", - "Last": 102, - "LastCursor": "MTAy", + "First": "UHJvZHVjdCAxLTA6MTAx", + "Last": "UHJvZHVjdCAxLTE6MTAy", "Items": [ { "Id": 101, @@ -90,16 +82,12 @@ } ``` -## Brand 3 +## 3 ```json { - "HasNextPage": true, - "HasPreviousPage": false, - "First": 201, - "FirstCursor": "MjAx", - "Last": 202, - "LastCursor": "MjAy", + "First": "UHJvZHVjdCAyLTA6MjAx", + "Last": "UHJvZHVjdCAyLTE6MjAy", "Items": [ { "Id": 201, diff --git a/src/HotChocolate/Pagination/test/Pagination.EntityFramework.Tests/__snapshots__/IntegrationPagingHelperTests.BatchPaging_Last_5.md b/src/HotChocolate/Pagination/test/Pagination.EntityFramework.Tests/__snapshots__/IntegrationPagingHelperTests.BatchPaging_Last_5.md index c8ef4b696d1..7c1eca27dcd 100644 --- a/src/HotChocolate/Pagination/test/Pagination.EntityFramework.Tests/__snapshots__/IntegrationPagingHelperTests.BatchPaging_Last_5.md +++ b/src/HotChocolate/Pagination/test/Pagination.EntityFramework.Tests/__snapshots__/IntegrationPagingHelperTests.BatchPaging_Last_5.md @@ -1,19 +1,15 @@ # BatchPaging_Last_5 -## Brand 1 +## 1 ```json { - "HasNextPage": false, - "HasPreviousPage": true, - "First": 1, - "FirstCursor": "MQ==", - "Last": 2, - "LastCursor": "Mg==", + "First": "MTAw", + "Last": "OTk=", "Items": [ { - "Id": 1, - "Name": "Product 0-0", + "Id": 100, + "Name": "Product 0-99", "Description": null, "Price": 0.0, "ImageFileName": null, @@ -27,8 +23,8 @@ "OnReorder": false }, { - "Id": 2, - "Name": "Product 0-1", + "Id": 99, + "Name": "Product 0-98", "Description": null, "Price": 0.0, "ImageFileName": null, @@ -45,20 +41,16 @@ } ``` -## Brand 2 +## 2 ```json { - "HasNextPage": false, - "HasPreviousPage": true, - "First": 101, - "FirstCursor": "MTAx", - "Last": 102, - "LastCursor": "MTAy", + "First": "MjAw", + "Last": "MTk5", "Items": [ { - "Id": 101, - "Name": "Product 1-0", + "Id": 200, + "Name": "Product 1-99", "Description": null, "Price": 0.0, "ImageFileName": null, @@ -72,8 +64,8 @@ "OnReorder": false }, { - "Id": 102, - "Name": "Product 1-1", + "Id": 199, + "Name": "Product 1-98", "Description": null, "Price": 0.0, "ImageFileName": null, @@ -90,20 +82,16 @@ } ``` -## Brand 3 +## 3 ```json { - "HasNextPage": false, - "HasPreviousPage": true, - "First": 201, - "FirstCursor": "MjAx", - "Last": 202, - "LastCursor": "MjAy", + "First": "MzAw", + "Last": "Mjk5", "Items": [ { - "Id": 201, - "Name": "Product 2-0", + "Id": 300, + "Name": "Product 2-99", "Description": null, "Price": 0.0, "ImageFileName": null, @@ -117,8 +105,8 @@ "OnReorder": false }, { - "Id": 202, - "Name": "Product 2-1", + "Id": 299, + "Name": "Product 2-98", "Description": null, "Price": 0.0, "ImageFileName": null, diff --git a/src/HotChocolate/Pagination/test/Pagination.EntityFramework.Tests/__snapshots__/IntegrationPagingHelperTests.Nested_Paging_First_2.md b/src/HotChocolate/Pagination/test/Pagination.EntityFramework.Tests/__snapshots__/IntegrationPagingHelperTests.Nested_Paging_First_2.md new file mode 100644 index 00000000000..9edceb90815 --- /dev/null +++ b/src/HotChocolate/Pagination/test/Pagination.EntityFramework.Tests/__snapshots__/IntegrationPagingHelperTests.Nested_Paging_First_2.md @@ -0,0 +1,56 @@ +# Nested_Paging_First_2 + +```json +{ + "data": { + "brands": { + "edges": [ + { + "cursor": "QnJhbmQwOjE=" + }, + { + "cursor": "QnJhbmQxOjI=" + } + ], + "nodes": [ + { + "products": { + "nodes": [ + { + "name": "Product 0-0" + }, + { + "name": "Product 0-1" + } + ], + "pageInfo": { + "hasNextPage": true, + "hasPreviousPage": false, + "startCursor": "UHJvZHVjdCAwLTA6MQ==", + "endCursor": "UHJvZHVjdCAwLTE6Mg==" + } + } + }, + { + "products": { + "nodes": [ + { + "name": "Product 1-0" + }, + { + "name": "Product 1-1" + } + ], + "pageInfo": { + "hasNextPage": true, + "hasPreviousPage": false, + "startCursor": "UHJvZHVjdCAxLTA6MTAx", + "endCursor": "UHJvZHVjdCAxLTE6MTAy" + } + } + } + ] + } + } +} +``` diff --git a/src/HotChocolate/Pagination/test/Pagination.EntityFramework.Tests/__snapshots__/PagingHelperTests.Batch_Fetch_First_2_Items.md b/src/HotChocolate/Pagination/test/Pagination.EntityFramework.Tests/__snapshots__/PagingHelperTests.Batch_Fetch_First_2_Items.md index dcbf70b2dea..5f0f515d13a 100644 --- a/src/HotChocolate/Pagination/test/Pagination.EntityFramework.Tests/__snapshots__/PagingHelperTests.Batch_Fetch_First_2_Items.md +++ b/src/HotChocolate/Pagination/test/Pagination.EntityFramework.Tests/__snapshots__/PagingHelperTests.Batch_Fetch_First_2_Items.md @@ -1,8 +1,12 @@ # Batch_Fetch_First_2_Items +## 1 + ```json { - "PageKey { Key = 1, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ + "First": "UHJvZHVjdCAwLTA6MQ==", + "Last": "UHJvZHVjdCAwLTE6Mg==", + "Items": [ { "Id": 1, "Name": "Product 0-0", @@ -12,47 +16,7 @@ "TypeId": 1, "Type": null, "BrandId": 1, - "Brand": { - "Id": 1, - "Name": "Brand0", - "DisplayName": "BrandDisplay0", - "AlwaysNull": null, - "Products": [ - { - "Id": 2, - "Name": "Product 0-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 1, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 11, - "Name": "Product 0-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 1, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country0" - } - } - }, + "Brand": null, "AvailableStock": 0, "RestockThreshold": 0, "MaxStockThreshold": 0, @@ -67,54 +31,23 @@ "TypeId": 1, "Type": null, "BrandId": 1, - "Brand": { - "Id": 1, - "Name": "Brand0", - "DisplayName": "BrandDisplay0", - "AlwaysNull": null, - "Products": [ - { - "Id": 1, - "Name": "Product 0-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 1, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 11, - "Name": "Product 0-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 1, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country0" - } - } - }, + "Brand": null, "AvailableStock": 0, "RestockThreshold": 0, "MaxStockThreshold": 0, "OnReorder": false } - ], - "PageKey { Key = 2, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ + ] +} +``` + +## 2 + +```json +{ + "First": "UHJvZHVjdCAxLTA6MTAx", + "Last": "UHJvZHVjdCAxLTE6MTAy", + "Items": [ { "Id": 101, "Name": "Product 1-0", @@ -124,47 +57,7 @@ "TypeId": 1, "Type": null, "BrandId": 2, - "Brand": { - "Id": 2, - "Name": "Brand1", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 102, - "Name": "Product 1-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 2, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 111, - "Name": "Product 1-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 2, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country1" - } - } - }, + "Brand": null, "AvailableStock": 0, "RestockThreshold": 0, "MaxStockThreshold": 0, @@ -179,54 +72,23 @@ "TypeId": 1, "Type": null, "BrandId": 2, - "Brand": { - "Id": 2, - "Name": "Brand1", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 101, - "Name": "Product 1-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 2, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 111, - "Name": "Product 1-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 2, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country1" - } - } - }, + "Brand": null, "AvailableStock": 0, "RestockThreshold": 0, "MaxStockThreshold": 0, "OnReorder": false } - ], - "PageKey { Key = 3, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ + ] +} +``` + +## 3 + +```json +{ + "First": "UHJvZHVjdCAyLTA6MjAx", + "Last": "UHJvZHVjdCAyLTE6MjAy", + "Items": [ { "Id": 201, "Name": "Product 2-0", @@ -236,47 +98,7 @@ "TypeId": 1, "Type": null, "BrandId": 3, - "Brand": { - "Id": 3, - "Name": "Brand2", - "DisplayName": "BrandDisplay2", - "AlwaysNull": null, - "Products": [ - { - "Id": 202, - "Name": "Product 2-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 3, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 211, - "Name": "Product 2-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 3, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country2" - } - } - }, + "Brand": null, "AvailableStock": 0, "RestockThreshold": 0, "MaxStockThreshold": 0, @@ -291,10911 +113,7 @@ "TypeId": 1, "Type": null, "BrandId": 3, - "Brand": { - "Id": 3, - "Name": "Brand2", - "DisplayName": "BrandDisplay2", - "AlwaysNull": null, - "Products": [ - { - "Id": 201, - "Name": "Product 2-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 3, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 211, - "Name": "Product 2-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 3, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country2" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 4, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 301, - "Name": "Product 3-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 4, - "Brand": { - "Id": 4, - "Name": "Brand3", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 302, - "Name": "Product 3-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 4, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 311, - "Name": "Product 3-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 4, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country3" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 302, - "Name": "Product 3-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 4, - "Brand": { - "Id": 4, - "Name": "Brand3", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 301, - "Name": "Product 3-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 4, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 311, - "Name": "Product 3-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 4, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country3" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 5, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 401, - "Name": "Product 4-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 5, - "Brand": { - "Id": 5, - "Name": "Brand4", - "DisplayName": "BrandDisplay4", - "AlwaysNull": null, - "Products": [ - { - "Id": 402, - "Name": "Product 4-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 5, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 411, - "Name": "Product 4-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 5, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country4" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 402, - "Name": "Product 4-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 5, - "Brand": { - "Id": 5, - "Name": "Brand4", - "DisplayName": "BrandDisplay4", - "AlwaysNull": null, - "Products": [ - { - "Id": 401, - "Name": "Product 4-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 5, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 411, - "Name": "Product 4-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 5, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country4" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 6, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 501, - "Name": "Product 5-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 6, - "Brand": { - "Id": 6, - "Name": "Brand5", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 502, - "Name": "Product 5-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 6, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 511, - "Name": "Product 5-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 6, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country5" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 502, - "Name": "Product 5-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 6, - "Brand": { - "Id": 6, - "Name": "Brand5", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 501, - "Name": "Product 5-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 6, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 511, - "Name": "Product 5-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 6, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country5" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 7, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 601, - "Name": "Product 6-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 7, - "Brand": { - "Id": 7, - "Name": "Brand6", - "DisplayName": "BrandDisplay6", - "AlwaysNull": null, - "Products": [ - { - "Id": 602, - "Name": "Product 6-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 7, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 611, - "Name": "Product 6-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 7, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country6" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 602, - "Name": "Product 6-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 7, - "Brand": { - "Id": 7, - "Name": "Brand6", - "DisplayName": "BrandDisplay6", - "AlwaysNull": null, - "Products": [ - { - "Id": 601, - "Name": "Product 6-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 7, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 611, - "Name": "Product 6-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 7, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country6" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 8, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 701, - "Name": "Product 7-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 8, - "Brand": { - "Id": 8, - "Name": "Brand7", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 702, - "Name": "Product 7-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 8, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 711, - "Name": "Product 7-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 8, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country7" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 702, - "Name": "Product 7-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 8, - "Brand": { - "Id": 8, - "Name": "Brand7", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 701, - "Name": "Product 7-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 8, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 711, - "Name": "Product 7-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 8, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country7" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 9, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 801, - "Name": "Product 8-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 9, - "Brand": { - "Id": 9, - "Name": "Brand8", - "DisplayName": "BrandDisplay8", - "AlwaysNull": null, - "Products": [ - { - "Id": 802, - "Name": "Product 8-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 9, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 811, - "Name": "Product 8-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 9, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country8" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 802, - "Name": "Product 8-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 9, - "Brand": { - "Id": 9, - "Name": "Brand8", - "DisplayName": "BrandDisplay8", - "AlwaysNull": null, - "Products": [ - { - "Id": 801, - "Name": "Product 8-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 9, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 811, - "Name": "Product 8-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 9, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country8" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 10, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 901, - "Name": "Product 9-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 10, - "Brand": { - "Id": 10, - "Name": "Brand9", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 902, - "Name": "Product 9-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 10, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 911, - "Name": "Product 9-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 10, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country9" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 902, - "Name": "Product 9-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 10, - "Brand": { - "Id": 10, - "Name": "Brand9", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 901, - "Name": "Product 9-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 10, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 911, - "Name": "Product 9-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 10, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country9" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 11, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 1001, - "Name": "Product 10-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 11, - "Brand": { - "Id": 11, - "Name": "Brand10", - "DisplayName": "BrandDisplay10", - "AlwaysNull": null, - "Products": [ - { - "Id": 1002, - "Name": "Product 10-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 11, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1011, - "Name": "Product 10-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 11, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country10" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1002, - "Name": "Product 10-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 11, - "Brand": { - "Id": 11, - "Name": "Brand10", - "DisplayName": "BrandDisplay10", - "AlwaysNull": null, - "Products": [ - { - "Id": 1001, - "Name": "Product 10-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 11, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1011, - "Name": "Product 10-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 11, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country10" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 12, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 1101, - "Name": "Product 11-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 12, - "Brand": { - "Id": 12, - "Name": "Brand11", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 1102, - "Name": "Product 11-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 12, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1111, - "Name": "Product 11-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 12, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country11" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1102, - "Name": "Product 11-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 12, - "Brand": { - "Id": 12, - "Name": "Brand11", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 1101, - "Name": "Product 11-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 12, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1111, - "Name": "Product 11-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 12, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country11" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 13, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 1201, - "Name": "Product 12-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 13, - "Brand": { - "Id": 13, - "Name": "Brand12", - "DisplayName": "BrandDisplay12", - "AlwaysNull": null, - "Products": [ - { - "Id": 1202, - "Name": "Product 12-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 13, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1211, - "Name": "Product 12-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 13, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country12" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1202, - "Name": "Product 12-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 13, - "Brand": { - "Id": 13, - "Name": "Brand12", - "DisplayName": "BrandDisplay12", - "AlwaysNull": null, - "Products": [ - { - "Id": 1201, - "Name": "Product 12-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 13, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1211, - "Name": "Product 12-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 13, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country12" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 14, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 1301, - "Name": "Product 13-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 14, - "Brand": { - "Id": 14, - "Name": "Brand13", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 1302, - "Name": "Product 13-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 14, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1311, - "Name": "Product 13-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 14, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country13" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1302, - "Name": "Product 13-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 14, - "Brand": { - "Id": 14, - "Name": "Brand13", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 1301, - "Name": "Product 13-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 14, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1311, - "Name": "Product 13-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 14, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country13" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 15, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 1401, - "Name": "Product 14-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 15, - "Brand": { - "Id": 15, - "Name": "Brand14", - "DisplayName": "BrandDisplay14", - "AlwaysNull": null, - "Products": [ - { - "Id": 1402, - "Name": "Product 14-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 15, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1411, - "Name": "Product 14-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 15, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country14" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1402, - "Name": "Product 14-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 15, - "Brand": { - "Id": 15, - "Name": "Brand14", - "DisplayName": "BrandDisplay14", - "AlwaysNull": null, - "Products": [ - { - "Id": 1401, - "Name": "Product 14-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 15, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1411, - "Name": "Product 14-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 15, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country14" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 16, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 1501, - "Name": "Product 15-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 16, - "Brand": { - "Id": 16, - "Name": "Brand15", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 1502, - "Name": "Product 15-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 16, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1511, - "Name": "Product 15-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 16, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country15" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1502, - "Name": "Product 15-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 16, - "Brand": { - "Id": 16, - "Name": "Brand15", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 1501, - "Name": "Product 15-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 16, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1511, - "Name": "Product 15-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 16, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country15" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 17, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 1601, - "Name": "Product 16-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 17, - "Brand": { - "Id": 17, - "Name": "Brand16", - "DisplayName": "BrandDisplay16", - "AlwaysNull": null, - "Products": [ - { - "Id": 1602, - "Name": "Product 16-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 17, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1611, - "Name": "Product 16-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 17, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country16" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1602, - "Name": "Product 16-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 17, - "Brand": { - "Id": 17, - "Name": "Brand16", - "DisplayName": "BrandDisplay16", - "AlwaysNull": null, - "Products": [ - { - "Id": 1601, - "Name": "Product 16-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 17, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1611, - "Name": "Product 16-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 17, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country16" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 18, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 1701, - "Name": "Product 17-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 18, - "Brand": { - "Id": 18, - "Name": "Brand17", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 1702, - "Name": "Product 17-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 18, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1711, - "Name": "Product 17-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 18, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country17" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1702, - "Name": "Product 17-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 18, - "Brand": { - "Id": 18, - "Name": "Brand17", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 1701, - "Name": "Product 17-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 18, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1711, - "Name": "Product 17-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 18, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country17" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 19, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 1801, - "Name": "Product 18-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 19, - "Brand": { - "Id": 19, - "Name": "Brand18", - "DisplayName": "BrandDisplay18", - "AlwaysNull": null, - "Products": [ - { - "Id": 1802, - "Name": "Product 18-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 19, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1811, - "Name": "Product 18-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 19, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country18" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1802, - "Name": "Product 18-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 19, - "Brand": { - "Id": 19, - "Name": "Brand18", - "DisplayName": "BrandDisplay18", - "AlwaysNull": null, - "Products": [ - { - "Id": 1801, - "Name": "Product 18-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 19, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1811, - "Name": "Product 18-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 19, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country18" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 20, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 1901, - "Name": "Product 19-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 20, - "Brand": { - "Id": 20, - "Name": "Brand19", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 1902, - "Name": "Product 19-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 20, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1911, - "Name": "Product 19-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 20, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country19" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1902, - "Name": "Product 19-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 20, - "Brand": { - "Id": 20, - "Name": "Brand19", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 1901, - "Name": "Product 19-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 20, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 1911, - "Name": "Product 19-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 20, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country19" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 21, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 2001, - "Name": "Product 20-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 21, - "Brand": { - "Id": 21, - "Name": "Brand20", - "DisplayName": "BrandDisplay20", - "AlwaysNull": null, - "Products": [ - { - "Id": 2002, - "Name": "Product 20-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 21, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2011, - "Name": "Product 20-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 21, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country20" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2002, - "Name": "Product 20-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 21, - "Brand": { - "Id": 21, - "Name": "Brand20", - "DisplayName": "BrandDisplay20", - "AlwaysNull": null, - "Products": [ - { - "Id": 2001, - "Name": "Product 20-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 21, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2011, - "Name": "Product 20-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 21, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country20" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 22, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 2101, - "Name": "Product 21-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 22, - "Brand": { - "Id": 22, - "Name": "Brand21", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 2102, - "Name": "Product 21-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 22, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2111, - "Name": "Product 21-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 22, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country21" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2102, - "Name": "Product 21-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 22, - "Brand": { - "Id": 22, - "Name": "Brand21", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 2101, - "Name": "Product 21-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 22, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2111, - "Name": "Product 21-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 22, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country21" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 23, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 2201, - "Name": "Product 22-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 23, - "Brand": { - "Id": 23, - "Name": "Brand22", - "DisplayName": "BrandDisplay22", - "AlwaysNull": null, - "Products": [ - { - "Id": 2202, - "Name": "Product 22-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 23, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2211, - "Name": "Product 22-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 23, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country22" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2202, - "Name": "Product 22-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 23, - "Brand": { - "Id": 23, - "Name": "Brand22", - "DisplayName": "BrandDisplay22", - "AlwaysNull": null, - "Products": [ - { - "Id": 2201, - "Name": "Product 22-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 23, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2211, - "Name": "Product 22-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 23, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country22" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 24, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 2301, - "Name": "Product 23-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 24, - "Brand": { - "Id": 24, - "Name": "Brand23", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 2302, - "Name": "Product 23-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 24, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2311, - "Name": "Product 23-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 24, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country23" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2302, - "Name": "Product 23-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 24, - "Brand": { - "Id": 24, - "Name": "Brand23", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 2301, - "Name": "Product 23-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 24, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2311, - "Name": "Product 23-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 24, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country23" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 25, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 2401, - "Name": "Product 24-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 25, - "Brand": { - "Id": 25, - "Name": "Brand24", - "DisplayName": "BrandDisplay24", - "AlwaysNull": null, - "Products": [ - { - "Id": 2402, - "Name": "Product 24-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 25, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2411, - "Name": "Product 24-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 25, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country24" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2402, - "Name": "Product 24-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 25, - "Brand": { - "Id": 25, - "Name": "Brand24", - "DisplayName": "BrandDisplay24", - "AlwaysNull": null, - "Products": [ - { - "Id": 2401, - "Name": "Product 24-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 25, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2411, - "Name": "Product 24-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 25, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country24" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 26, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 2501, - "Name": "Product 25-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 26, - "Brand": { - "Id": 26, - "Name": "Brand25", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 2502, - "Name": "Product 25-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 26, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2511, - "Name": "Product 25-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 26, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country25" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2502, - "Name": "Product 25-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 26, - "Brand": { - "Id": 26, - "Name": "Brand25", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 2501, - "Name": "Product 25-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 26, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2511, - "Name": "Product 25-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 26, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country25" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 27, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 2601, - "Name": "Product 26-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 27, - "Brand": { - "Id": 27, - "Name": "Brand26", - "DisplayName": "BrandDisplay26", - "AlwaysNull": null, - "Products": [ - { - "Id": 2602, - "Name": "Product 26-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 27, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2611, - "Name": "Product 26-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 27, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country26" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2602, - "Name": "Product 26-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 27, - "Brand": { - "Id": 27, - "Name": "Brand26", - "DisplayName": "BrandDisplay26", - "AlwaysNull": null, - "Products": [ - { - "Id": 2601, - "Name": "Product 26-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 27, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2611, - "Name": "Product 26-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 27, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country26" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 28, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 2701, - "Name": "Product 27-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 28, - "Brand": { - "Id": 28, - "Name": "Brand27", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 2702, - "Name": "Product 27-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 28, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2711, - "Name": "Product 27-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 28, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country27" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2702, - "Name": "Product 27-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 28, - "Brand": { - "Id": 28, - "Name": "Brand27", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 2701, - "Name": "Product 27-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 28, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2711, - "Name": "Product 27-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 28, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country27" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 29, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 2801, - "Name": "Product 28-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 29, - "Brand": { - "Id": 29, - "Name": "Brand28", - "DisplayName": "BrandDisplay28", - "AlwaysNull": null, - "Products": [ - { - "Id": 2802, - "Name": "Product 28-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 29, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2811, - "Name": "Product 28-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 29, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country28" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2802, - "Name": "Product 28-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 29, - "Brand": { - "Id": 29, - "Name": "Brand28", - "DisplayName": "BrandDisplay28", - "AlwaysNull": null, - "Products": [ - { - "Id": 2801, - "Name": "Product 28-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 29, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2811, - "Name": "Product 28-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 29, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country28" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 30, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 2901, - "Name": "Product 29-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 30, - "Brand": { - "Id": 30, - "Name": "Brand29", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 2902, - "Name": "Product 29-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 30, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2911, - "Name": "Product 29-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 30, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country29" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2902, - "Name": "Product 29-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 30, - "Brand": { - "Id": 30, - "Name": "Brand29", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 2901, - "Name": "Product 29-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 30, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 2911, - "Name": "Product 29-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 30, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country29" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 31, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 3001, - "Name": "Product 30-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 31, - "Brand": { - "Id": 31, - "Name": "Brand30", - "DisplayName": "BrandDisplay30", - "AlwaysNull": null, - "Products": [ - { - "Id": 3002, - "Name": "Product 30-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 31, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3011, - "Name": "Product 30-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 31, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country30" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3002, - "Name": "Product 30-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 31, - "Brand": { - "Id": 31, - "Name": "Brand30", - "DisplayName": "BrandDisplay30", - "AlwaysNull": null, - "Products": [ - { - "Id": 3001, - "Name": "Product 30-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 31, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3011, - "Name": "Product 30-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 31, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country30" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 32, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 3101, - "Name": "Product 31-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 32, - "Brand": { - "Id": 32, - "Name": "Brand31", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 3102, - "Name": "Product 31-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 32, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3111, - "Name": "Product 31-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 32, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country31" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3102, - "Name": "Product 31-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 32, - "Brand": { - "Id": 32, - "Name": "Brand31", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 3101, - "Name": "Product 31-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 32, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3111, - "Name": "Product 31-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 32, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country31" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 33, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 3201, - "Name": "Product 32-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 33, - "Brand": { - "Id": 33, - "Name": "Brand32", - "DisplayName": "BrandDisplay32", - "AlwaysNull": null, - "Products": [ - { - "Id": 3202, - "Name": "Product 32-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 33, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3211, - "Name": "Product 32-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 33, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country32" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3202, - "Name": "Product 32-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 33, - "Brand": { - "Id": 33, - "Name": "Brand32", - "DisplayName": "BrandDisplay32", - "AlwaysNull": null, - "Products": [ - { - "Id": 3201, - "Name": "Product 32-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 33, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3211, - "Name": "Product 32-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 33, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country32" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 34, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 3301, - "Name": "Product 33-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 34, - "Brand": { - "Id": 34, - "Name": "Brand33", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 3302, - "Name": "Product 33-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 34, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3311, - "Name": "Product 33-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 34, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country33" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3302, - "Name": "Product 33-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 34, - "Brand": { - "Id": 34, - "Name": "Brand33", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 3301, - "Name": "Product 33-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 34, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3311, - "Name": "Product 33-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 34, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country33" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 35, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 3401, - "Name": "Product 34-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 35, - "Brand": { - "Id": 35, - "Name": "Brand34", - "DisplayName": "BrandDisplay34", - "AlwaysNull": null, - "Products": [ - { - "Id": 3402, - "Name": "Product 34-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 35, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3411, - "Name": "Product 34-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 35, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country34" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3402, - "Name": "Product 34-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 35, - "Brand": { - "Id": 35, - "Name": "Brand34", - "DisplayName": "BrandDisplay34", - "AlwaysNull": null, - "Products": [ - { - "Id": 3401, - "Name": "Product 34-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 35, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3411, - "Name": "Product 34-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 35, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country34" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 36, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 3501, - "Name": "Product 35-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 36, - "Brand": { - "Id": 36, - "Name": "Brand35", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 3502, - "Name": "Product 35-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 36, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3511, - "Name": "Product 35-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 36, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country35" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3502, - "Name": "Product 35-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 36, - "Brand": { - "Id": 36, - "Name": "Brand35", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 3501, - "Name": "Product 35-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 36, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3511, - "Name": "Product 35-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 36, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country35" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 37, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 3601, - "Name": "Product 36-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 37, - "Brand": { - "Id": 37, - "Name": "Brand36", - "DisplayName": "BrandDisplay36", - "AlwaysNull": null, - "Products": [ - { - "Id": 3602, - "Name": "Product 36-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 37, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3611, - "Name": "Product 36-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 37, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country36" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3602, - "Name": "Product 36-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 37, - "Brand": { - "Id": 37, - "Name": "Brand36", - "DisplayName": "BrandDisplay36", - "AlwaysNull": null, - "Products": [ - { - "Id": 3601, - "Name": "Product 36-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 37, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3611, - "Name": "Product 36-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 37, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country36" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 38, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 3701, - "Name": "Product 37-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 38, - "Brand": { - "Id": 38, - "Name": "Brand37", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 3702, - "Name": "Product 37-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 38, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3711, - "Name": "Product 37-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 38, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country37" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3702, - "Name": "Product 37-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 38, - "Brand": { - "Id": 38, - "Name": "Brand37", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 3701, - "Name": "Product 37-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 38, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3711, - "Name": "Product 37-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 38, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country37" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 39, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 3801, - "Name": "Product 38-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 39, - "Brand": { - "Id": 39, - "Name": "Brand38", - "DisplayName": "BrandDisplay38", - "AlwaysNull": null, - "Products": [ - { - "Id": 3802, - "Name": "Product 38-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 39, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3811, - "Name": "Product 38-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 39, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country38" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3802, - "Name": "Product 38-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 39, - "Brand": { - "Id": 39, - "Name": "Brand38", - "DisplayName": "BrandDisplay38", - "AlwaysNull": null, - "Products": [ - { - "Id": 3801, - "Name": "Product 38-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 39, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3811, - "Name": "Product 38-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 39, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country38" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 40, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 3901, - "Name": "Product 39-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 40, - "Brand": { - "Id": 40, - "Name": "Brand39", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 3902, - "Name": "Product 39-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 40, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3911, - "Name": "Product 39-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 40, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country39" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3902, - "Name": "Product 39-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 40, - "Brand": { - "Id": 40, - "Name": "Brand39", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 3901, - "Name": "Product 39-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 40, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 3911, - "Name": "Product 39-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 40, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country39" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 41, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 4001, - "Name": "Product 40-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 41, - "Brand": { - "Id": 41, - "Name": "Brand40", - "DisplayName": "BrandDisplay40", - "AlwaysNull": null, - "Products": [ - { - "Id": 4002, - "Name": "Product 40-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 41, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4011, - "Name": "Product 40-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 41, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country40" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4002, - "Name": "Product 40-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 41, - "Brand": { - "Id": 41, - "Name": "Brand40", - "DisplayName": "BrandDisplay40", - "AlwaysNull": null, - "Products": [ - { - "Id": 4001, - "Name": "Product 40-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 41, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4011, - "Name": "Product 40-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 41, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country40" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 42, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 4101, - "Name": "Product 41-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 42, - "Brand": { - "Id": 42, - "Name": "Brand41", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 4102, - "Name": "Product 41-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 42, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4111, - "Name": "Product 41-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 42, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country41" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4102, - "Name": "Product 41-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 42, - "Brand": { - "Id": 42, - "Name": "Brand41", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 4101, - "Name": "Product 41-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 42, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4111, - "Name": "Product 41-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 42, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country41" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 43, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 4201, - "Name": "Product 42-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 43, - "Brand": { - "Id": 43, - "Name": "Brand42", - "DisplayName": "BrandDisplay42", - "AlwaysNull": null, - "Products": [ - { - "Id": 4202, - "Name": "Product 42-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 43, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4211, - "Name": "Product 42-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 43, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country42" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4202, - "Name": "Product 42-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 43, - "Brand": { - "Id": 43, - "Name": "Brand42", - "DisplayName": "BrandDisplay42", - "AlwaysNull": null, - "Products": [ - { - "Id": 4201, - "Name": "Product 42-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 43, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4211, - "Name": "Product 42-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 43, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country42" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 44, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 4301, - "Name": "Product 43-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 44, - "Brand": { - "Id": 44, - "Name": "Brand43", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 4302, - "Name": "Product 43-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 44, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4311, - "Name": "Product 43-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 44, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country43" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4302, - "Name": "Product 43-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 44, - "Brand": { - "Id": 44, - "Name": "Brand43", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 4301, - "Name": "Product 43-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 44, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4311, - "Name": "Product 43-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 44, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country43" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 45, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 4401, - "Name": "Product 44-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 45, - "Brand": { - "Id": 45, - "Name": "Brand44", - "DisplayName": "BrandDisplay44", - "AlwaysNull": null, - "Products": [ - { - "Id": 4402, - "Name": "Product 44-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 45, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4411, - "Name": "Product 44-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 45, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country44" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4402, - "Name": "Product 44-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 45, - "Brand": { - "Id": 45, - "Name": "Brand44", - "DisplayName": "BrandDisplay44", - "AlwaysNull": null, - "Products": [ - { - "Id": 4401, - "Name": "Product 44-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 45, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4411, - "Name": "Product 44-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 45, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country44" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 46, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 4501, - "Name": "Product 45-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 46, - "Brand": { - "Id": 46, - "Name": "Brand45", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 4502, - "Name": "Product 45-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 46, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4511, - "Name": "Product 45-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 46, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country45" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4502, - "Name": "Product 45-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 46, - "Brand": { - "Id": 46, - "Name": "Brand45", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 4501, - "Name": "Product 45-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 46, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4511, - "Name": "Product 45-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 46, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country45" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 47, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 4601, - "Name": "Product 46-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 47, - "Brand": { - "Id": 47, - "Name": "Brand46", - "DisplayName": "BrandDisplay46", - "AlwaysNull": null, - "Products": [ - { - "Id": 4602, - "Name": "Product 46-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 47, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4611, - "Name": "Product 46-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 47, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country46" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4602, - "Name": "Product 46-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 47, - "Brand": { - "Id": 47, - "Name": "Brand46", - "DisplayName": "BrandDisplay46", - "AlwaysNull": null, - "Products": [ - { - "Id": 4601, - "Name": "Product 46-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 47, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4611, - "Name": "Product 46-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 47, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country46" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 48, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 4701, - "Name": "Product 47-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 48, - "Brand": { - "Id": 48, - "Name": "Brand47", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 4702, - "Name": "Product 47-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 48, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4711, - "Name": "Product 47-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 48, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country47" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4702, - "Name": "Product 47-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 48, - "Brand": { - "Id": 48, - "Name": "Brand47", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 4701, - "Name": "Product 47-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 48, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4711, - "Name": "Product 47-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 48, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country47" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 49, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 4801, - "Name": "Product 48-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 49, - "Brand": { - "Id": 49, - "Name": "Brand48", - "DisplayName": "BrandDisplay48", - "AlwaysNull": null, - "Products": [ - { - "Id": 4802, - "Name": "Product 48-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 49, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4811, - "Name": "Product 48-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 49, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country48" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4802, - "Name": "Product 48-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 49, - "Brand": { - "Id": 49, - "Name": "Brand48", - "DisplayName": "BrandDisplay48", - "AlwaysNull": null, - "Products": [ - { - "Id": 4801, - "Name": "Product 48-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 49, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4811, - "Name": "Product 48-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 49, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country48" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 50, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 4901, - "Name": "Product 49-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 50, - "Brand": { - "Id": 50, - "Name": "Brand49", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 4902, - "Name": "Product 49-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 50, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4911, - "Name": "Product 49-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 50, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country49" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4902, - "Name": "Product 49-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 50, - "Brand": { - "Id": 50, - "Name": "Brand49", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 4901, - "Name": "Product 49-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 50, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 4911, - "Name": "Product 49-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 50, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country49" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 51, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 5001, - "Name": "Product 50-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 51, - "Brand": { - "Id": 51, - "Name": "Brand50", - "DisplayName": "BrandDisplay50", - "AlwaysNull": null, - "Products": [ - { - "Id": 5002, - "Name": "Product 50-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 51, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5011, - "Name": "Product 50-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 51, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country50" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5002, - "Name": "Product 50-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 51, - "Brand": { - "Id": 51, - "Name": "Brand50", - "DisplayName": "BrandDisplay50", - "AlwaysNull": null, - "Products": [ - { - "Id": 5001, - "Name": "Product 50-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 51, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5011, - "Name": "Product 50-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 51, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country50" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 52, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 5101, - "Name": "Product 51-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 52, - "Brand": { - "Id": 52, - "Name": "Brand51", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 5102, - "Name": "Product 51-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 52, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5111, - "Name": "Product 51-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 52, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country51" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5102, - "Name": "Product 51-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 52, - "Brand": { - "Id": 52, - "Name": "Brand51", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 5101, - "Name": "Product 51-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 52, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5111, - "Name": "Product 51-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 52, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country51" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 53, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 5201, - "Name": "Product 52-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 53, - "Brand": { - "Id": 53, - "Name": "Brand52", - "DisplayName": "BrandDisplay52", - "AlwaysNull": null, - "Products": [ - { - "Id": 5202, - "Name": "Product 52-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 53, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5211, - "Name": "Product 52-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 53, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country52" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5202, - "Name": "Product 52-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 53, - "Brand": { - "Id": 53, - "Name": "Brand52", - "DisplayName": "BrandDisplay52", - "AlwaysNull": null, - "Products": [ - { - "Id": 5201, - "Name": "Product 52-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 53, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5211, - "Name": "Product 52-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 53, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country52" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 54, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 5301, - "Name": "Product 53-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 54, - "Brand": { - "Id": 54, - "Name": "Brand53", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 5302, - "Name": "Product 53-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 54, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5311, - "Name": "Product 53-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 54, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country53" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5302, - "Name": "Product 53-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 54, - "Brand": { - "Id": 54, - "Name": "Brand53", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 5301, - "Name": "Product 53-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 54, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5311, - "Name": "Product 53-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 54, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country53" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 55, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 5401, - "Name": "Product 54-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 55, - "Brand": { - "Id": 55, - "Name": "Brand54", - "DisplayName": "BrandDisplay54", - "AlwaysNull": null, - "Products": [ - { - "Id": 5402, - "Name": "Product 54-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 55, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5411, - "Name": "Product 54-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 55, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country54" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5402, - "Name": "Product 54-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 55, - "Brand": { - "Id": 55, - "Name": "Brand54", - "DisplayName": "BrandDisplay54", - "AlwaysNull": null, - "Products": [ - { - "Id": 5401, - "Name": "Product 54-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 55, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5411, - "Name": "Product 54-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 55, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country54" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 56, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 5501, - "Name": "Product 55-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 56, - "Brand": { - "Id": 56, - "Name": "Brand55", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 5502, - "Name": "Product 55-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 56, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5511, - "Name": "Product 55-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 56, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country55" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5502, - "Name": "Product 55-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 56, - "Brand": { - "Id": 56, - "Name": "Brand55", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 5501, - "Name": "Product 55-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 56, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5511, - "Name": "Product 55-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 56, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country55" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 57, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 5601, - "Name": "Product 56-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 57, - "Brand": { - "Id": 57, - "Name": "Brand56", - "DisplayName": "BrandDisplay56", - "AlwaysNull": null, - "Products": [ - { - "Id": 5602, - "Name": "Product 56-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 57, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5611, - "Name": "Product 56-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 57, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country56" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5602, - "Name": "Product 56-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 57, - "Brand": { - "Id": 57, - "Name": "Brand56", - "DisplayName": "BrandDisplay56", - "AlwaysNull": null, - "Products": [ - { - "Id": 5601, - "Name": "Product 56-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 57, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5611, - "Name": "Product 56-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 57, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country56" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 58, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 5701, - "Name": "Product 57-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 58, - "Brand": { - "Id": 58, - "Name": "Brand57", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 5702, - "Name": "Product 57-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 58, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5711, - "Name": "Product 57-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 58, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country57" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5702, - "Name": "Product 57-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 58, - "Brand": { - "Id": 58, - "Name": "Brand57", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 5701, - "Name": "Product 57-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 58, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5711, - "Name": "Product 57-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 58, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country57" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 59, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 5801, - "Name": "Product 58-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 59, - "Brand": { - "Id": 59, - "Name": "Brand58", - "DisplayName": "BrandDisplay58", - "AlwaysNull": null, - "Products": [ - { - "Id": 5802, - "Name": "Product 58-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 59, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5811, - "Name": "Product 58-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 59, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country58" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5802, - "Name": "Product 58-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 59, - "Brand": { - "Id": 59, - "Name": "Brand58", - "DisplayName": "BrandDisplay58", - "AlwaysNull": null, - "Products": [ - { - "Id": 5801, - "Name": "Product 58-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 59, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5811, - "Name": "Product 58-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 59, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country58" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 60, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 5901, - "Name": "Product 59-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 60, - "Brand": { - "Id": 60, - "Name": "Brand59", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 5902, - "Name": "Product 59-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 60, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5911, - "Name": "Product 59-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 60, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country59" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5902, - "Name": "Product 59-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 60, - "Brand": { - "Id": 60, - "Name": "Brand59", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 5901, - "Name": "Product 59-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 60, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 5911, - "Name": "Product 59-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 60, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country59" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 61, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 6001, - "Name": "Product 60-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 61, - "Brand": { - "Id": 61, - "Name": "Brand60", - "DisplayName": "BrandDisplay60", - "AlwaysNull": null, - "Products": [ - { - "Id": 6002, - "Name": "Product 60-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 61, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6011, - "Name": "Product 60-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 61, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country60" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6002, - "Name": "Product 60-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 61, - "Brand": { - "Id": 61, - "Name": "Brand60", - "DisplayName": "BrandDisplay60", - "AlwaysNull": null, - "Products": [ - { - "Id": 6001, - "Name": "Product 60-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 61, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6011, - "Name": "Product 60-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 61, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country60" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 62, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 6101, - "Name": "Product 61-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 62, - "Brand": { - "Id": 62, - "Name": "Brand61", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 6102, - "Name": "Product 61-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 62, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6111, - "Name": "Product 61-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 62, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country61" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6102, - "Name": "Product 61-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 62, - "Brand": { - "Id": 62, - "Name": "Brand61", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 6101, - "Name": "Product 61-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 62, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6111, - "Name": "Product 61-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 62, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country61" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 63, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 6201, - "Name": "Product 62-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 63, - "Brand": { - "Id": 63, - "Name": "Brand62", - "DisplayName": "BrandDisplay62", - "AlwaysNull": null, - "Products": [ - { - "Id": 6202, - "Name": "Product 62-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 63, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6211, - "Name": "Product 62-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 63, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country62" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6202, - "Name": "Product 62-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 63, - "Brand": { - "Id": 63, - "Name": "Brand62", - "DisplayName": "BrandDisplay62", - "AlwaysNull": null, - "Products": [ - { - "Id": 6201, - "Name": "Product 62-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 63, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6211, - "Name": "Product 62-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 63, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country62" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 64, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 6301, - "Name": "Product 63-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 64, - "Brand": { - "Id": 64, - "Name": "Brand63", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 6302, - "Name": "Product 63-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 64, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6311, - "Name": "Product 63-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 64, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country63" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6302, - "Name": "Product 63-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 64, - "Brand": { - "Id": 64, - "Name": "Brand63", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 6301, - "Name": "Product 63-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 64, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6311, - "Name": "Product 63-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 64, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country63" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 65, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 6401, - "Name": "Product 64-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 65, - "Brand": { - "Id": 65, - "Name": "Brand64", - "DisplayName": "BrandDisplay64", - "AlwaysNull": null, - "Products": [ - { - "Id": 6402, - "Name": "Product 64-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 65, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6411, - "Name": "Product 64-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 65, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country64" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6402, - "Name": "Product 64-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 65, - "Brand": { - "Id": 65, - "Name": "Brand64", - "DisplayName": "BrandDisplay64", - "AlwaysNull": null, - "Products": [ - { - "Id": 6401, - "Name": "Product 64-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 65, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6411, - "Name": "Product 64-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 65, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country64" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 66, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 6501, - "Name": "Product 65-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 66, - "Brand": { - "Id": 66, - "Name": "Brand65", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 6502, - "Name": "Product 65-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 66, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6511, - "Name": "Product 65-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 66, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country65" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6502, - "Name": "Product 65-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 66, - "Brand": { - "Id": 66, - "Name": "Brand65", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 6501, - "Name": "Product 65-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 66, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6511, - "Name": "Product 65-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 66, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country65" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 67, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 6601, - "Name": "Product 66-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 67, - "Brand": { - "Id": 67, - "Name": "Brand66", - "DisplayName": "BrandDisplay66", - "AlwaysNull": null, - "Products": [ - { - "Id": 6602, - "Name": "Product 66-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 67, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6611, - "Name": "Product 66-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 67, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country66" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6602, - "Name": "Product 66-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 67, - "Brand": { - "Id": 67, - "Name": "Brand66", - "DisplayName": "BrandDisplay66", - "AlwaysNull": null, - "Products": [ - { - "Id": 6601, - "Name": "Product 66-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 67, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6611, - "Name": "Product 66-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 67, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country66" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 68, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 6701, - "Name": "Product 67-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 68, - "Brand": { - "Id": 68, - "Name": "Brand67", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 6702, - "Name": "Product 67-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 68, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6711, - "Name": "Product 67-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 68, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country67" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6702, - "Name": "Product 67-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 68, - "Brand": { - "Id": 68, - "Name": "Brand67", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 6701, - "Name": "Product 67-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 68, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6711, - "Name": "Product 67-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 68, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country67" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 69, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 6801, - "Name": "Product 68-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 69, - "Brand": { - "Id": 69, - "Name": "Brand68", - "DisplayName": "BrandDisplay68", - "AlwaysNull": null, - "Products": [ - { - "Id": 6802, - "Name": "Product 68-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 69, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6811, - "Name": "Product 68-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 69, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country68" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6802, - "Name": "Product 68-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 69, - "Brand": { - "Id": 69, - "Name": "Brand68", - "DisplayName": "BrandDisplay68", - "AlwaysNull": null, - "Products": [ - { - "Id": 6801, - "Name": "Product 68-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 69, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6811, - "Name": "Product 68-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 69, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country68" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 70, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 6901, - "Name": "Product 69-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 70, - "Brand": { - "Id": 70, - "Name": "Brand69", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 6902, - "Name": "Product 69-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 70, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6911, - "Name": "Product 69-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 70, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country69" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6902, - "Name": "Product 69-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 70, - "Brand": { - "Id": 70, - "Name": "Brand69", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 6901, - "Name": "Product 69-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 70, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 6911, - "Name": "Product 69-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 70, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country69" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 71, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 7001, - "Name": "Product 70-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 71, - "Brand": { - "Id": 71, - "Name": "Brand70", - "DisplayName": "BrandDisplay70", - "AlwaysNull": null, - "Products": [ - { - "Id": 7002, - "Name": "Product 70-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 71, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7011, - "Name": "Product 70-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 71, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country70" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7002, - "Name": "Product 70-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 71, - "Brand": { - "Id": 71, - "Name": "Brand70", - "DisplayName": "BrandDisplay70", - "AlwaysNull": null, - "Products": [ - { - "Id": 7001, - "Name": "Product 70-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 71, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7011, - "Name": "Product 70-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 71, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country70" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 72, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 7101, - "Name": "Product 71-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 72, - "Brand": { - "Id": 72, - "Name": "Brand71", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 7102, - "Name": "Product 71-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 72, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7111, - "Name": "Product 71-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 72, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country71" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7102, - "Name": "Product 71-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 72, - "Brand": { - "Id": 72, - "Name": "Brand71", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 7101, - "Name": "Product 71-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 72, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7111, - "Name": "Product 71-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 72, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country71" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 73, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 7201, - "Name": "Product 72-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 73, - "Brand": { - "Id": 73, - "Name": "Brand72", - "DisplayName": "BrandDisplay72", - "AlwaysNull": null, - "Products": [ - { - "Id": 7202, - "Name": "Product 72-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 73, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7211, - "Name": "Product 72-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 73, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country72" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7202, - "Name": "Product 72-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 73, - "Brand": { - "Id": 73, - "Name": "Brand72", - "DisplayName": "BrandDisplay72", - "AlwaysNull": null, - "Products": [ - { - "Id": 7201, - "Name": "Product 72-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 73, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7211, - "Name": "Product 72-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 73, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country72" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 74, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 7301, - "Name": "Product 73-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 74, - "Brand": { - "Id": 74, - "Name": "Brand73", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 7302, - "Name": "Product 73-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 74, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7311, - "Name": "Product 73-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 74, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country73" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7302, - "Name": "Product 73-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 74, - "Brand": { - "Id": 74, - "Name": "Brand73", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 7301, - "Name": "Product 73-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 74, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7311, - "Name": "Product 73-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 74, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country73" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 75, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 7401, - "Name": "Product 74-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 75, - "Brand": { - "Id": 75, - "Name": "Brand74", - "DisplayName": "BrandDisplay74", - "AlwaysNull": null, - "Products": [ - { - "Id": 7402, - "Name": "Product 74-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 75, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7411, - "Name": "Product 74-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 75, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country74" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7402, - "Name": "Product 74-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 75, - "Brand": { - "Id": 75, - "Name": "Brand74", - "DisplayName": "BrandDisplay74", - "AlwaysNull": null, - "Products": [ - { - "Id": 7401, - "Name": "Product 74-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 75, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7411, - "Name": "Product 74-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 75, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country74" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 76, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 7501, - "Name": "Product 75-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 76, - "Brand": { - "Id": 76, - "Name": "Brand75", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 7502, - "Name": "Product 75-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 76, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7511, - "Name": "Product 75-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 76, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country75" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7502, - "Name": "Product 75-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 76, - "Brand": { - "Id": 76, - "Name": "Brand75", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 7501, - "Name": "Product 75-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 76, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7511, - "Name": "Product 75-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 76, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country75" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 77, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 7601, - "Name": "Product 76-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 77, - "Brand": { - "Id": 77, - "Name": "Brand76", - "DisplayName": "BrandDisplay76", - "AlwaysNull": null, - "Products": [ - { - "Id": 7602, - "Name": "Product 76-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 77, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7611, - "Name": "Product 76-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 77, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country76" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7602, - "Name": "Product 76-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 77, - "Brand": { - "Id": 77, - "Name": "Brand76", - "DisplayName": "BrandDisplay76", - "AlwaysNull": null, - "Products": [ - { - "Id": 7601, - "Name": "Product 76-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 77, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7611, - "Name": "Product 76-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 77, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country76" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 78, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 7701, - "Name": "Product 77-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 78, - "Brand": { - "Id": 78, - "Name": "Brand77", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 7702, - "Name": "Product 77-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 78, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7711, - "Name": "Product 77-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 78, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country77" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7702, - "Name": "Product 77-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 78, - "Brand": { - "Id": 78, - "Name": "Brand77", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 7701, - "Name": "Product 77-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 78, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7711, - "Name": "Product 77-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 78, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country77" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 79, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 7801, - "Name": "Product 78-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 79, - "Brand": { - "Id": 79, - "Name": "Brand78", - "DisplayName": "BrandDisplay78", - "AlwaysNull": null, - "Products": [ - { - "Id": 7802, - "Name": "Product 78-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 79, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7811, - "Name": "Product 78-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 79, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country78" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7802, - "Name": "Product 78-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 79, - "Brand": { - "Id": 79, - "Name": "Brand78", - "DisplayName": "BrandDisplay78", - "AlwaysNull": null, - "Products": [ - { - "Id": 7801, - "Name": "Product 78-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 79, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7811, - "Name": "Product 78-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 79, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country78" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 80, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 7901, - "Name": "Product 79-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 80, - "Brand": { - "Id": 80, - "Name": "Brand79", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 7902, - "Name": "Product 79-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 80, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7911, - "Name": "Product 79-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 80, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country79" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7902, - "Name": "Product 79-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 80, - "Brand": { - "Id": 80, - "Name": "Brand79", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 7901, - "Name": "Product 79-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 80, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 7911, - "Name": "Product 79-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 80, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country79" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 81, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 8001, - "Name": "Product 80-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 81, - "Brand": { - "Id": 81, - "Name": "Brand80", - "DisplayName": "BrandDisplay80", - "AlwaysNull": null, - "Products": [ - { - "Id": 8002, - "Name": "Product 80-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 81, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8011, - "Name": "Product 80-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 81, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country80" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8002, - "Name": "Product 80-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 81, - "Brand": { - "Id": 81, - "Name": "Brand80", - "DisplayName": "BrandDisplay80", - "AlwaysNull": null, - "Products": [ - { - "Id": 8001, - "Name": "Product 80-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 81, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8011, - "Name": "Product 80-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 81, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country80" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 82, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 8101, - "Name": "Product 81-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 82, - "Brand": { - "Id": 82, - "Name": "Brand81", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 8102, - "Name": "Product 81-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 82, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8111, - "Name": "Product 81-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 82, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country81" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8102, - "Name": "Product 81-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 82, - "Brand": { - "Id": 82, - "Name": "Brand81", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 8101, - "Name": "Product 81-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 82, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8111, - "Name": "Product 81-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 82, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country81" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 83, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 8201, - "Name": "Product 82-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 83, - "Brand": { - "Id": 83, - "Name": "Brand82", - "DisplayName": "BrandDisplay82", - "AlwaysNull": null, - "Products": [ - { - "Id": 8202, - "Name": "Product 82-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 83, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8211, - "Name": "Product 82-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 83, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country82" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8202, - "Name": "Product 82-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 83, - "Brand": { - "Id": 83, - "Name": "Brand82", - "DisplayName": "BrandDisplay82", - "AlwaysNull": null, - "Products": [ - { - "Id": 8201, - "Name": "Product 82-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 83, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8211, - "Name": "Product 82-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 83, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country82" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 84, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 8301, - "Name": "Product 83-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 84, - "Brand": { - "Id": 84, - "Name": "Brand83", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 8302, - "Name": "Product 83-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 84, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8311, - "Name": "Product 83-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 84, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country83" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8302, - "Name": "Product 83-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 84, - "Brand": { - "Id": 84, - "Name": "Brand83", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 8301, - "Name": "Product 83-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 84, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8311, - "Name": "Product 83-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 84, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country83" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 85, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 8401, - "Name": "Product 84-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 85, - "Brand": { - "Id": 85, - "Name": "Brand84", - "DisplayName": "BrandDisplay84", - "AlwaysNull": null, - "Products": [ - { - "Id": 8402, - "Name": "Product 84-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 85, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8411, - "Name": "Product 84-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 85, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country84" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8402, - "Name": "Product 84-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 85, - "Brand": { - "Id": 85, - "Name": "Brand84", - "DisplayName": "BrandDisplay84", - "AlwaysNull": null, - "Products": [ - { - "Id": 8401, - "Name": "Product 84-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 85, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8411, - "Name": "Product 84-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 85, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country84" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 86, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 8501, - "Name": "Product 85-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 86, - "Brand": { - "Id": 86, - "Name": "Brand85", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 8502, - "Name": "Product 85-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 86, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8511, - "Name": "Product 85-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 86, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country85" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8502, - "Name": "Product 85-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 86, - "Brand": { - "Id": 86, - "Name": "Brand85", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 8501, - "Name": "Product 85-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 86, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8511, - "Name": "Product 85-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 86, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country85" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 87, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 8601, - "Name": "Product 86-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 87, - "Brand": { - "Id": 87, - "Name": "Brand86", - "DisplayName": "BrandDisplay86", - "AlwaysNull": null, - "Products": [ - { - "Id": 8602, - "Name": "Product 86-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 87, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8611, - "Name": "Product 86-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 87, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country86" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8602, - "Name": "Product 86-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 87, - "Brand": { - "Id": 87, - "Name": "Brand86", - "DisplayName": "BrandDisplay86", - "AlwaysNull": null, - "Products": [ - { - "Id": 8601, - "Name": "Product 86-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 87, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8611, - "Name": "Product 86-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 87, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country86" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 88, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 8701, - "Name": "Product 87-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 88, - "Brand": { - "Id": 88, - "Name": "Brand87", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 8702, - "Name": "Product 87-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 88, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8711, - "Name": "Product 87-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 88, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country87" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8702, - "Name": "Product 87-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 88, - "Brand": { - "Id": 88, - "Name": "Brand87", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 8701, - "Name": "Product 87-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 88, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8711, - "Name": "Product 87-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 88, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country87" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 89, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 8801, - "Name": "Product 88-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 89, - "Brand": { - "Id": 89, - "Name": "Brand88", - "DisplayName": "BrandDisplay88", - "AlwaysNull": null, - "Products": [ - { - "Id": 8802, - "Name": "Product 88-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 89, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8811, - "Name": "Product 88-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 89, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country88" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8802, - "Name": "Product 88-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 89, - "Brand": { - "Id": 89, - "Name": "Brand88", - "DisplayName": "BrandDisplay88", - "AlwaysNull": null, - "Products": [ - { - "Id": 8801, - "Name": "Product 88-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 89, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8811, - "Name": "Product 88-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 89, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country88" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 90, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 8901, - "Name": "Product 89-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 90, - "Brand": { - "Id": 90, - "Name": "Brand89", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 8902, - "Name": "Product 89-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 90, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8911, - "Name": "Product 89-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 90, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country89" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8902, - "Name": "Product 89-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 90, - "Brand": { - "Id": 90, - "Name": "Brand89", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 8901, - "Name": "Product 89-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 90, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 8911, - "Name": "Product 89-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 90, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country89" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 91, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 9001, - "Name": "Product 90-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 91, - "Brand": { - "Id": 91, - "Name": "Brand90", - "DisplayName": "BrandDisplay90", - "AlwaysNull": null, - "Products": [ - { - "Id": 9002, - "Name": "Product 90-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 91, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9011, - "Name": "Product 90-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 91, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country90" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9002, - "Name": "Product 90-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 91, - "Brand": { - "Id": 91, - "Name": "Brand90", - "DisplayName": "BrandDisplay90", - "AlwaysNull": null, - "Products": [ - { - "Id": 9001, - "Name": "Product 90-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 91, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9011, - "Name": "Product 90-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 91, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country90" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 92, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 9101, - "Name": "Product 91-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 92, - "Brand": { - "Id": 92, - "Name": "Brand91", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 9102, - "Name": "Product 91-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 92, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9111, - "Name": "Product 91-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 92, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country91" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9102, - "Name": "Product 91-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 92, - "Brand": { - "Id": 92, - "Name": "Brand91", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 9101, - "Name": "Product 91-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 92, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9111, - "Name": "Product 91-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 92, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country91" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 93, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 9201, - "Name": "Product 92-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 93, - "Brand": { - "Id": 93, - "Name": "Brand92", - "DisplayName": "BrandDisplay92", - "AlwaysNull": null, - "Products": [ - { - "Id": 9202, - "Name": "Product 92-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 93, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9211, - "Name": "Product 92-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 93, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country92" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9202, - "Name": "Product 92-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 93, - "Brand": { - "Id": 93, - "Name": "Brand92", - "DisplayName": "BrandDisplay92", - "AlwaysNull": null, - "Products": [ - { - "Id": 9201, - "Name": "Product 92-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 93, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9211, - "Name": "Product 92-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 93, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country92" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 94, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 9301, - "Name": "Product 93-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 94, - "Brand": { - "Id": 94, - "Name": "Brand93", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 9302, - "Name": "Product 93-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 94, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9311, - "Name": "Product 93-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 94, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country93" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9302, - "Name": "Product 93-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 94, - "Brand": { - "Id": 94, - "Name": "Brand93", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 9301, - "Name": "Product 93-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 94, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9311, - "Name": "Product 93-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 94, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country93" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 95, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 9401, - "Name": "Product 94-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 95, - "Brand": { - "Id": 95, - "Name": "Brand94", - "DisplayName": "BrandDisplay94", - "AlwaysNull": null, - "Products": [ - { - "Id": 9402, - "Name": "Product 94-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 95, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9411, - "Name": "Product 94-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 95, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country94" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9402, - "Name": "Product 94-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 95, - "Brand": { - "Id": 95, - "Name": "Brand94", - "DisplayName": "BrandDisplay94", - "AlwaysNull": null, - "Products": [ - { - "Id": 9401, - "Name": "Product 94-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 95, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9411, - "Name": "Product 94-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 95, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country94" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 96, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 9501, - "Name": "Product 95-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 96, - "Brand": { - "Id": 96, - "Name": "Brand95", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 9502, - "Name": "Product 95-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 96, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9511, - "Name": "Product 95-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 96, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country95" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9502, - "Name": "Product 95-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 96, - "Brand": { - "Id": 96, - "Name": "Brand95", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 9501, - "Name": "Product 95-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 96, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9511, - "Name": "Product 95-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 96, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country95" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 97, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 9601, - "Name": "Product 96-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 97, - "Brand": { - "Id": 97, - "Name": "Brand96", - "DisplayName": "BrandDisplay96", - "AlwaysNull": null, - "Products": [ - { - "Id": 9602, - "Name": "Product 96-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 97, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9611, - "Name": "Product 96-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 97, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country96" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9602, - "Name": "Product 96-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 97, - "Brand": { - "Id": 97, - "Name": "Brand96", - "DisplayName": "BrandDisplay96", - "AlwaysNull": null, - "Products": [ - { - "Id": 9601, - "Name": "Product 96-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 97, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9611, - "Name": "Product 96-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 97, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country96" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 98, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 9701, - "Name": "Product 97-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 98, - "Brand": { - "Id": 98, - "Name": "Brand97", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 9702, - "Name": "Product 97-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 98, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9711, - "Name": "Product 97-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 98, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country97" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9702, - "Name": "Product 97-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 98, - "Brand": { - "Id": 98, - "Name": "Brand97", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 9701, - "Name": "Product 97-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 98, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9711, - "Name": "Product 97-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 98, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country97" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 99, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 9801, - "Name": "Product 98-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 99, - "Brand": { - "Id": 99, - "Name": "Brand98", - "DisplayName": "BrandDisplay98", - "AlwaysNull": null, - "Products": [ - { - "Id": 9802, - "Name": "Product 98-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 99, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9811, - "Name": "Product 98-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 99, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country98" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9802, - "Name": "Product 98-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 99, - "Brand": { - "Id": 99, - "Name": "Brand98", - "DisplayName": "BrandDisplay98", - "AlwaysNull": null, - "Products": [ - { - "Id": 9801, - "Name": "Product 98-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 99, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9811, - "Name": "Product 98-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 99, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country98" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "PageKey { Key = 100, PagingArgs = PagingArguments { First = 2, After = , Last = , Before = } }": [ - { - "Id": 9901, - "Name": "Product 99-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 100, - "Brand": { - "Id": 100, - "Name": "Brand99", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 9902, - "Name": "Product 99-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 100, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9911, - "Name": "Product 99-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 100, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country99" - } - } - }, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9902, - "Name": "Product 99-1", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 100, - "Brand": { - "Id": 100, - "Name": "Brand99", - "DisplayName": null, - "AlwaysNull": null, - "Products": [ - { - "Id": 9901, - "Name": "Product 99-0", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 100, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - }, - { - "Id": 9911, - "Name": "Product 99-10", - "Description": null, - "Price": 0.0, - "ImageFileName": null, - "TypeId": 1, - "Type": null, - "BrandId": 100, - "AvailableStock": 0, - "RestockThreshold": 0, - "MaxStockThreshold": 0, - "OnReorder": false - } - ], - "BrandDetails": { - "Country": { - "Name": "Country99" - } - } - }, + "Brand": null, "AvailableStock": 0, "RestockThreshold": 0, "MaxStockThreshold": 0, @@ -11204,3 +122,4 @@ ] } ``` +