Bump samples to 3.5.1 and remove old CodeSamples (#1095)
* Bump samples to 3.5.1 * Switch to using * to always get the latest nuget version. * Removed deprecated samples
This commit is contained in:
Родитель
dce186c7d5
Коммит
e1ef934997
|
@ -1,27 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<AzureFunctionsVersion>v2</AzureFunctionsVersion>
|
||||
<AssemblyName>Cosmos.Samples.AzureFunctions</AssemblyName>
|
||||
<RootNamespace>Cosmos.Samples.AzureFunctions</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\AppSettings.json" Link="AppSettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.27" />
|
||||
<PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.0.0" />
|
||||
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Update="host.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="local.settings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,68 +0,0 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Azure.Cosmos;
|
||||
using Microsoft.Azure.WebJobs;
|
||||
using Microsoft.Azure.WebJobs.Extensions.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Cosmos.Samples.AzureFunctions
|
||||
{
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
// Prerequisites -
|
||||
//
|
||||
// 1. An Azure Cosmos account -
|
||||
// https://azure.microsoft.com/en-us/itemation/articles/itemdb-create-account/
|
||||
//
|
||||
// 2. Microsoft.Azure.Cosmos NuGet package -
|
||||
// http://www.nuget.org/packages/Microsoft.Azure.Cosmos/
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
// Sample - demonstrates how to maintain a Cosmos client and reuse the instance among Azure Function executions.
|
||||
//
|
||||
// More information: https://github.com/Azure/azure-functions-host/wiki/Managing-Connections
|
||||
|
||||
public class AzureFunctionsCosmosClient
|
||||
{
|
||||
private CosmosClient cosmosClient;
|
||||
public AzureFunctionsCosmosClient(CosmosClient cosmosClient)
|
||||
{
|
||||
this.cosmosClient = cosmosClient;
|
||||
}
|
||||
|
||||
|
||||
[FunctionName("CosmosClient")]
|
||||
public async Task<IActionResult> Run(
|
||||
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
|
||||
ILogger log)
|
||||
{
|
||||
log.LogInformation("C# HTTP trigger function processed a request.");
|
||||
|
||||
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
|
||||
Item data = JsonConvert.DeserializeObject<Item>(requestBody);
|
||||
if (data == null)
|
||||
{
|
||||
return new BadRequestObjectResult($"Cannot parse body.");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(data.Id))
|
||||
{
|
||||
data.Id = Guid.NewGuid().ToString();
|
||||
}
|
||||
|
||||
var container = this.cosmosClient.GetContainer("mydb", "mycoll");
|
||||
|
||||
try
|
||||
{
|
||||
var result = await container.CreateItemAsync<Item>(data, new PartitionKey(data.Id));
|
||||
return new OkObjectResult(result.Resource.Id);
|
||||
}
|
||||
catch (CosmosException cosmosException)
|
||||
{
|
||||
return new BadRequestObjectResult($"Failed to create item. Cosmos Status Code {cosmosException.StatusCode}, Sub Status Code {cosmosException.SubStatusCode}: {cosmosException.Message}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
using Newtonsoft.Json;
|
||||
|
||||
namespace Cosmos.Samples.AzureFunctions
|
||||
{
|
||||
public class Item
|
||||
{
|
||||
[JsonProperty(PropertyName = "id")]
|
||||
public string Id { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "description")]
|
||||
public string Description { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "isComplete")]
|
||||
public bool Completed { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
using System;
|
||||
using Microsoft.Azure.Cosmos;
|
||||
using Microsoft.Azure.Cosmos.Fluent;
|
||||
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
[assembly: FunctionsStartup(typeof(Cosmos.Samples.AzureFunctions.Startup))]
|
||||
|
||||
namespace Cosmos.Samples.AzureFunctions
|
||||
{
|
||||
public class Startup : FunctionsStartup
|
||||
{
|
||||
private static IConfigurationRoot configuration = new ConfigurationBuilder()
|
||||
.SetBasePath(Environment.CurrentDirectory)
|
||||
.AddJsonFile("AppSettings.json", optional: true, reloadOnChange: true)
|
||||
.AddEnvironmentVariables()
|
||||
.Build();
|
||||
|
||||
public override void Configure(IFunctionsHostBuilder builder)
|
||||
{
|
||||
// Register the CosmosClient as a Singleton
|
||||
|
||||
builder.Services.AddSingleton((s) => {
|
||||
string endpoint = configuration["EndPointUrl"];
|
||||
if (string.IsNullOrEmpty(endpoint))
|
||||
{
|
||||
throw new ArgumentNullException("Please specify a valid endpoint in the appSettings.json file or your Azure Functions Settings.");
|
||||
}
|
||||
|
||||
string authKey = configuration["AuthorizationKey"];
|
||||
if (string.IsNullOrEmpty(authKey) || string.Equals(authKey, "Super secret key"))
|
||||
{
|
||||
throw new ArgumentException("Please specify a valid AuthorizationKey in the appSettings.json file or your Azure Functions Settings.");
|
||||
}
|
||||
|
||||
CosmosClientBuilder configurationBuilder = new CosmosClientBuilder(endpoint, authKey);
|
||||
return configurationBuilder
|
||||
.Build();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"version": "2.0"
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"IsEncrypted": false,
|
||||
"Values": {
|
||||
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
|
||||
"FUNCTIONS_WORKER_RUNTIME": "dotnet"
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\AppSettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,227 +0,0 @@
|
|||
namespace Cosmos.Samples.Shared
|
||||
{
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Azure.Cosmos;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
class Program
|
||||
{
|
||||
//Read configuration
|
||||
private static readonly string databaseId = "samples";
|
||||
private static readonly string containerId = "container-samples";
|
||||
private static readonly string partitionKey = "/activityId";
|
||||
|
||||
private static Database database = null;
|
||||
|
||||
// Async main requires c# 7.1 which is set in the csproj with the LangVersion attribute
|
||||
// <Main>
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
IConfigurationRoot configuration = new ConfigurationBuilder()
|
||||
.AddJsonFile("appSettings.json")
|
||||
.Build();
|
||||
|
||||
string endpoint = configuration["EndPointUrl"];
|
||||
if (string.IsNullOrEmpty(endpoint))
|
||||
{
|
||||
throw new ArgumentNullException("Please specify a valid endpoint in the appSettings.json");
|
||||
}
|
||||
|
||||
string authKey = configuration["AuthorizationKey"];
|
||||
if (string.IsNullOrEmpty(authKey) || string.Equals(authKey, "Super secret key"))
|
||||
{
|
||||
throw new ArgumentException("Please specify a valid AuthorizationKey in the appSettings.json");
|
||||
}
|
||||
|
||||
//Read the Cosmos endpointUrl and authorisationKeys from configuration
|
||||
//These values are available from the Azure Management Portal on the Cosmos Account Blade under "Keys"
|
||||
//NB > Keep these values in a safe & secure location. Together they provide Administrative access to your Cosmos account
|
||||
using (CosmosClient client = new CosmosClient(endpoint, authKey))
|
||||
{
|
||||
await Program.RunContainerDemo(client);
|
||||
}
|
||||
}
|
||||
catch (CosmosException cre)
|
||||
{
|
||||
Console.WriteLine(cre.ToString());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Exception baseException = e.GetBaseException();
|
||||
Console.WriteLine("Error: {0}, Message: {1}", e.Message, baseException.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.WriteLine("End of demo, press any key to exit.");
|
||||
Console.ReadKey();
|
||||
}
|
||||
}
|
||||
// </Main>
|
||||
|
||||
/// <summary>
|
||||
/// Run through basic container access methods as a console app demo.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
// <RunContainerDemo>
|
||||
private static async Task RunContainerDemo(CosmosClient client)
|
||||
{
|
||||
// Create the database if necessary
|
||||
await Program.Setup(client);
|
||||
|
||||
Container simpleContainer = await Program.CreateContainer();
|
||||
|
||||
await Program.CreateContainerWithCustomIndexingPolicy();
|
||||
|
||||
await Program.CreateContainerWithTtlExpiration();
|
||||
|
||||
await Program.GetAndChangeContainerPerformance(simpleContainer);
|
||||
|
||||
await Program.ReadContainerProperties();
|
||||
|
||||
await Program.ListContainersInDatabase();
|
||||
|
||||
// Uncomment to delete container!
|
||||
// await Program.DeleteContainer();
|
||||
}
|
||||
// </RunContainerDemo>
|
||||
|
||||
private static async Task Setup(CosmosClient client)
|
||||
{
|
||||
database = await client.CreateDatabaseIfNotExistsAsync(databaseId);
|
||||
}
|
||||
|
||||
// <CreateContainer>
|
||||
private static async Task<Container> CreateContainer()
|
||||
{
|
||||
// Set throughput to the minimum value of 400 RU/s
|
||||
ContainerResponse simpleContainer = await database.CreateContainerIfNotExistsAsync(
|
||||
id: containerId,
|
||||
partitionKeyPath: partitionKey,
|
||||
throughput: 400);
|
||||
|
||||
Console.WriteLine($"\n1.1. Created container :{simpleContainer.Container.Id}");
|
||||
return simpleContainer;
|
||||
}
|
||||
// </CreateContainer>
|
||||
|
||||
// <CreateContainerWithCustomIndexingPolicy>
|
||||
private static async Task CreateContainerWithCustomIndexingPolicy()
|
||||
{
|
||||
// Create a container with custom index policy (consistent indexing)
|
||||
// We cover index policies in detail in IndexManagement sample project
|
||||
ContainerProperties containerProperties = new ContainerProperties(
|
||||
id: "SampleContainerWithCustomIndexPolicy",
|
||||
partitionKeyPath: partitionKey);
|
||||
containerProperties.IndexingPolicy.IndexingMode = IndexingMode.Consistent;
|
||||
|
||||
Container containerWithConsistentIndexing = await database.CreateContainerIfNotExistsAsync(
|
||||
containerProperties,
|
||||
throughput: 400);
|
||||
|
||||
Console.WriteLine($"1.2. Created Container {containerWithConsistentIndexing.Id}, with custom index policy \n");
|
||||
|
||||
await containerWithConsistentIndexing.DeleteContainerAsync();
|
||||
}
|
||||
// </CreateContainerWithCustomIndexingPolicy>
|
||||
|
||||
// <CreateContainerWithTtlExpiration>
|
||||
private static async Task CreateContainerWithTtlExpiration()
|
||||
{
|
||||
ContainerProperties properties = new ContainerProperties
|
||||
(id: "TtlExpiryContainer",
|
||||
partitionKeyPath: partitionKey);
|
||||
properties.DefaultTimeToLive = (int)TimeSpan.FromDays(1).TotalSeconds; //expire in 1 day
|
||||
|
||||
ContainerResponse ttlEnabledContainerResponse = await database.CreateContainerIfNotExistsAsync(
|
||||
containerProperties: properties);
|
||||
ContainerProperties returnedProperties = ttlEnabledContainerResponse;
|
||||
|
||||
Console.WriteLine($"\n1.3. Created Container \n{returnedProperties.Id} with TTL expiration of {returnedProperties.DefaultTimeToLive}");
|
||||
|
||||
await ttlEnabledContainerResponse.Container.DeleteContainerAsync();
|
||||
}
|
||||
// </CreateContainerWithTtlExpiration>
|
||||
|
||||
// <GetAndChangeContainerPerformance>
|
||||
private static async Task GetAndChangeContainerPerformance(Container simpleContainer)
|
||||
{
|
||||
|
||||
//*********************************************************************************************
|
||||
// Get configured performance (reserved throughput) of a CosmosContainer
|
||||
//**********************************************************************************************
|
||||
int? throughputResponse = await simpleContainer.ReadThroughputAsync();
|
||||
|
||||
Console.WriteLine($"\n2. Found throughput \n{throughputResponse}\nusing container's id \n{simpleContainer.Id}");
|
||||
|
||||
//******************************************************************************************************************
|
||||
// Change performance (reserved throughput) of CosmosContainer
|
||||
// Let's change the performance of the container to 500 RU/s
|
||||
//******************************************************************************************************************
|
||||
|
||||
await simpleContainer.ReplaceThroughputAsync(500);
|
||||
|
||||
Console.WriteLine("\n3. Replaced throughput. Throughput is now 500.\n");
|
||||
|
||||
// Get the offer again after replace
|
||||
throughputResponse = await simpleContainer.ReadThroughputAsync();
|
||||
|
||||
Console.WriteLine($"3. Found throughput \n{throughputResponse}\n using container's ResourceId {simpleContainer.Id}.\n");
|
||||
}
|
||||
// </GetAndChangeContainerPerformance>
|
||||
|
||||
// <ReadContainerProperties>
|
||||
private static async Task ReadContainerProperties()
|
||||
{
|
||||
//*************************************************
|
||||
// Get a CosmosContainer by its Id property
|
||||
//*************************************************
|
||||
Container container = database.GetContainer(containerId);
|
||||
ContainerProperties containerProperties = await container.ReadContainerAsync();
|
||||
|
||||
Console.WriteLine($"\n4. Found Container \n{containerProperties.Id}\n");
|
||||
}
|
||||
// </ReadContainerProperties>
|
||||
|
||||
/// <summary>
|
||||
/// List the container within a database by calling the GetContainerIterator (scan) API.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
// <ListContainersInDatabase>
|
||||
private static async Task ListContainersInDatabase()
|
||||
{
|
||||
Console.WriteLine("\n5. Reading all CosmosContainer resources for a database");
|
||||
|
||||
FeedIterator<ContainerProperties> resultSetIterator = database.GetContainerQueryIterator<ContainerProperties>();
|
||||
while (resultSetIterator.HasMoreResults)
|
||||
{
|
||||
foreach (ContainerProperties container in await resultSetIterator.ReadNextAsync())
|
||||
{
|
||||
Console.WriteLine(container.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
// </ListContainersInDatabase>
|
||||
|
||||
/// <summary>
|
||||
/// Delete a container
|
||||
/// </summary>
|
||||
/// <param name="simpleContainer"></param>
|
||||
// <DeleteContainer>
|
||||
private static async Task DeleteContainer()
|
||||
{
|
||||
await database.GetContainer(containerId).DeleteContainerAsync();
|
||||
Console.WriteLine("\n6. Deleted Container\n");
|
||||
}
|
||||
// </DeleteContainer>
|
||||
}
|
||||
|
||||
public class ToDoActivity
|
||||
{
|
||||
public string id = null;
|
||||
public string activityId = null;
|
||||
public string status = null;
|
||||
}
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.28010.2041
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DatabaseManagement", "DatabaseManagement\DatabaseManagement.csproj", "{F972386A-B03D-4453-88C7-948CB107C029}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ContainerManagement", "ContainerManagement\ContainerManagement.csproj", "{6ACA3641-A6DB-4D19-AC3F-F43A69DFB52F}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ItemManagement", "ItemManagement\ItemManagement.csproj", "{FF1C9654-E125-47ED-8EC1-E82156D5EED3}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Shared", "Shared\Shared.csproj", "{5A9CFB9C-7261-4DE9-9CCB-A8A6D0207B83}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Queries", "Queries\Queries.csproj", "{107BAEC4-BF37-4872-9193-AEE6F0A947E1}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServerSideScripts", "ServerSideScripts\ServerSideScripts.csproj", "{7FCC3B73-85FC-42A7-96AB-3D508BB871BD}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HandlerSample", "Handlers\HandlerSample.csproj", "{DAE99683-1049-4E8F-9580-5C9B5562D9A7}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AzureFunctions", "AzureFunctions\AzureFunctions.csproj", "{4D375AAB-E67E-4A0C-9418-F512F705C574}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NonPartitionContainerMigration", "NonPartitionContainerMigration\NonPartitionContainerMigration.csproj", "{C1A42351-39FC-4600-A235-FF5A90B02628}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{F972386A-B03D-4453-88C7-948CB107C029}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F972386A-B03D-4453-88C7-948CB107C029}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F972386A-B03D-4453-88C7-948CB107C029}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F972386A-B03D-4453-88C7-948CB107C029}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6ACA3641-A6DB-4D19-AC3F-F43A69DFB52F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6ACA3641-A6DB-4D19-AC3F-F43A69DFB52F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6ACA3641-A6DB-4D19-AC3F-F43A69DFB52F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6ACA3641-A6DB-4D19-AC3F-F43A69DFB52F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{FF1C9654-E125-47ED-8EC1-E82156D5EED3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FF1C9654-E125-47ED-8EC1-E82156D5EED3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FF1C9654-E125-47ED-8EC1-E82156D5EED3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FF1C9654-E125-47ED-8EC1-E82156D5EED3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5A9CFB9C-7261-4DE9-9CCB-A8A6D0207B83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5A9CFB9C-7261-4DE9-9CCB-A8A6D0207B83}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5A9CFB9C-7261-4DE9-9CCB-A8A6D0207B83}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5A9CFB9C-7261-4DE9-9CCB-A8A6D0207B83}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{107BAEC4-BF37-4872-9193-AEE6F0A947E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{107BAEC4-BF37-4872-9193-AEE6F0A947E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{107BAEC4-BF37-4872-9193-AEE6F0A947E1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{107BAEC4-BF37-4872-9193-AEE6F0A947E1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7FCC3B73-85FC-42A7-96AB-3D508BB871BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7FCC3B73-85FC-42A7-96AB-3D508BB871BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7FCC3B73-85FC-42A7-96AB-3D508BB871BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7FCC3B73-85FC-42A7-96AB-3D508BB871BD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{DAE99683-1049-4E8F-9580-5C9B5562D9A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DAE99683-1049-4E8F-9580-5C9B5562D9A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DAE99683-1049-4E8F-9580-5C9B5562D9A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DAE99683-1049-4E8F-9580-5C9B5562D9A7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4D375AAB-E67E-4A0C-9418-F512F705C574}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4D375AAB-E67E-4A0C-9418-F512F705C574}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4D375AAB-E67E-4A0C-9418-F512F705C574}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4D375AAB-E67E-4A0C-9418-F512F705C574}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C1A42351-39FC-4600-A235-FF5A90B02628}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C1A42351-39FC-4600-A235-FF5A90B02628}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C1A42351-39FC-4600-A235-FF5A90B02628}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C1A42351-39FC-4600-A235-FF5A90B02628}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {BB174784-6D22-454F-9F1C-7DE233164C11}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -1,20 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\AppSettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,111 +0,0 @@
|
|||
namespace Cosmos.Samples.Shared
|
||||
{
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Azure.Cosmos;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
internal class Program
|
||||
{
|
||||
//Read configuration
|
||||
private static readonly string databaseId = "samples";
|
||||
|
||||
// Async main requires c# 7.1 which is set in the csproj with the LangVersion attribute
|
||||
// <Main>
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
IConfigurationRoot configuration = new ConfigurationBuilder()
|
||||
.AddJsonFile("appSettings.json")
|
||||
.Build();
|
||||
|
||||
string endpoint = configuration["EndPointUrl"];
|
||||
if (string.IsNullOrEmpty(endpoint))
|
||||
{
|
||||
throw new ArgumentNullException("Please specify a valid endpoint in the appSettings.json");
|
||||
}
|
||||
|
||||
string authKey = configuration["AuthorizationKey"];
|
||||
if (string.IsNullOrEmpty(authKey) || string.Equals(authKey, "Super secret key"))
|
||||
{
|
||||
throw new ArgumentException("Please specify a valid AuthorizationKey in the appSettings.json");
|
||||
}
|
||||
|
||||
//Read the Cosmos endpointUrl and authorisationKeys from configuration
|
||||
//These values are available from the Azure Management Portal on the Cosmos Account Blade under "Keys"
|
||||
//NB > Keep these values in a safe & secure location. Together they provide Administrative access to your Cosmos account
|
||||
using (CosmosClient client = new CosmosClient(endpoint, authKey))
|
||||
{
|
||||
await Program.RunDatabaseDemo(client);
|
||||
}
|
||||
}
|
||||
catch (CosmosException cre)
|
||||
{
|
||||
Console.WriteLine(cre.ToString());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Exception baseException = e.GetBaseException();
|
||||
Console.WriteLine("Error: {0}, Message: {1}", e.Message, baseException.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.WriteLine("End of demo, press any key to exit.");
|
||||
Console.ReadKey();
|
||||
}
|
||||
}
|
||||
// </Main>
|
||||
|
||||
/// <summary>
|
||||
/// Run basic database meta data operations as a console application.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
// <RunDatabaseDemo>
|
||||
private static async Task RunDatabaseDemo(CosmosClient client)
|
||||
{
|
||||
// An object containing relevant information about the response
|
||||
DatabaseResponse databaseResponse = await client.CreateDatabaseIfNotExistsAsync(databaseId, 10000);
|
||||
|
||||
// A client side reference object that allows additional operations like ReadAsync
|
||||
Database database = databaseResponse;
|
||||
|
||||
// The response from Azure Cosmos
|
||||
DatabaseProperties properties = databaseResponse;
|
||||
|
||||
Console.WriteLine($"\n1. Create a database resource with id: {properties.Id} and last modified time stamp: {properties.LastModified}");
|
||||
Console.WriteLine($"\n2. Create a database resource request charge: {databaseResponse.RequestCharge} and Activity Id: {databaseResponse.ActivityId}");
|
||||
|
||||
// Read the database from Azure Cosmos
|
||||
DatabaseResponse readResponse = await database.ReadAsync();
|
||||
Console.WriteLine($"\n3. Read a database: {readResponse.Resource.Id}");
|
||||
|
||||
await readResponse.Database.CreateContainerAsync("testContainer", "/pk");
|
||||
|
||||
// Get the current throughput for the database
|
||||
int? throughputResponse = await database.ReadThroughputAsync();
|
||||
if (throughputResponse.HasValue)
|
||||
{
|
||||
Console.WriteLine($"\n4. Read a database throughput: {throughputResponse}");
|
||||
|
||||
// Update the current throughput for the database
|
||||
await database.ReplaceThroughputAsync(11000);
|
||||
}
|
||||
|
||||
Console.WriteLine("\n5. Reading all databases resources for an account");
|
||||
FeedIterator<DatabaseProperties> iterator = client.GetDatabaseQueryIterator<DatabaseProperties>();
|
||||
do
|
||||
{
|
||||
foreach (DatabaseProperties db in await iterator.ReadNextAsync())
|
||||
{
|
||||
Console.WriteLine(db.Id);
|
||||
}
|
||||
} while (iterator.HasMoreResults);
|
||||
|
||||
// Delete the database from Azure Cosmos.
|
||||
await database.DeleteAsync();
|
||||
Console.WriteLine($"\n6. Database {database.Id} deleted.");
|
||||
}
|
||||
// </RunDatabaseDemo>
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
namespace Cosmos.Samples.Handlers
|
||||
{
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Azure.Cosmos;
|
||||
|
||||
/// <summary>
|
||||
/// Handler that detects concurrency and etag issues
|
||||
/// </summary>
|
||||
class ConcurrencyHandler : RequestHandler
|
||||
{
|
||||
public override async Task<ResponseMessage> SendAsync(
|
||||
RequestMessage request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
|
||||
ResponseMessage response = await base.SendAsync(request, cancellationToken);
|
||||
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.PreconditionFailed)
|
||||
{
|
||||
response.Headers.Set("x-ms-substatus", "999");
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<AssemblyName>Cosmos.Samples.Handlers</AssemblyName>
|
||||
<RootNamespace>Cosmos.Samples.Handlers</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\AppSettings.json" Link="AppSettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.ApplicationInsights" Version="2.8.1" />
|
||||
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||
<PackageReference Include="Polly" Version="6.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -1,38 +0,0 @@
|
|||
namespace Cosmos.Samples.Handlers
|
||||
{
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.ApplicationInsights;
|
||||
using Microsoft.ApplicationInsights.DataContracts;
|
||||
using Microsoft.Azure.Cosmos;
|
||||
|
||||
/// <summary>
|
||||
/// This handler will send telemetry to Application Insights
|
||||
/// </summary>
|
||||
class LoggingHandler : RequestHandler
|
||||
{
|
||||
private readonly TelemetryClient telemetryClient;
|
||||
public LoggingHandler()
|
||||
{
|
||||
this.telemetryClient = new TelemetryClient();
|
||||
}
|
||||
|
||||
public override async Task<ResponseMessage> SendAsync(
|
||||
RequestMessage request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
|
||||
using (Microsoft.ApplicationInsights.Extensibility.IOperationHolder<RequestTelemetry> operation = this.telemetryClient.StartOperation<RequestTelemetry>("CosmosDBRequest"))
|
||||
{
|
||||
this.telemetryClient.TrackTrace($"{request.Method.Method} - {request.RequestUri.ToString()}");
|
||||
ResponseMessage response = await base.SendAsync(request, cancellationToken);
|
||||
|
||||
operation.Telemetry.ResponseCode = ((int)response.StatusCode).ToString();
|
||||
operation.Telemetry.Success = response.IsSuccessStatusCode;
|
||||
|
||||
this.telemetryClient.StopOperation(operation);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
using Newtonsoft.Json;
|
||||
|
||||
namespace Cosmos.Samples.Handlers.Models
|
||||
{
|
||||
public class Item
|
||||
{
|
||||
[JsonProperty(PropertyName = "id")]
|
||||
public string Id { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "description")]
|
||||
public string Description { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "isComplete")]
|
||||
public bool Completed { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,138 +0,0 @@
|
|||
namespace Cosmos.Samples.Handlers
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Cosmos.Samples.Handlers.Models;
|
||||
using Microsoft.Azure.Cosmos;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Azure.Cosmos.Fluent;
|
||||
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
// Prerequisites -
|
||||
//
|
||||
// 1. An Azure Cosmos account -
|
||||
// https://azure.microsoft.com/en-us/itemation/articles/itemdb-create-account/
|
||||
//
|
||||
// 2. Microsoft.Azure.Cosmos NuGet package -
|
||||
// http://www.nuget.org/packages/Microsoft.Azure.Cosmos/
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
// Sample - demonstrates how to work with custom Handlers in the SDK pipeline
|
||||
//
|
||||
// 1. LoggingHandler that will log all requests to Application Insights
|
||||
// 2. ConcurrencyHandler that will act upon requests that violate ETag concurrency
|
||||
// 3. ThrottlingHandler that will use Polly to handle retries on 429s
|
||||
|
||||
|
||||
public class Program
|
||||
{
|
||||
// Async main requires c# 7.1 which is set in the csproj with the LangVersion attribute
|
||||
// <Main>
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
IConfigurationRoot configuration = new ConfigurationBuilder()
|
||||
.AddJsonFile("appSettings.json")
|
||||
.Build();
|
||||
|
||||
string endpoint = configuration["EndPointUrl"];
|
||||
if (string.IsNullOrEmpty(endpoint))
|
||||
{
|
||||
throw new ArgumentNullException("Please specify a valid endpoint in the appSettings.json");
|
||||
}
|
||||
|
||||
string authKey = configuration["AuthorizationKey"];
|
||||
if (string.IsNullOrEmpty(authKey) || string.Equals(authKey, "Super secret key"))
|
||||
{
|
||||
throw new ArgumentException("Please specify a valid AuthorizationKey in the appSettings.json");
|
||||
}
|
||||
|
||||
// Connecting to Emulator. Change if you want a live account
|
||||
CosmosClientBuilder cosmosClientBuilder = new CosmosClientBuilder(endpoint, authKey);
|
||||
|
||||
cosmosClientBuilder.AddCustomHandlers(
|
||||
new LoggingHandler(),
|
||||
new ConcurrencyHandler(),
|
||||
new ThrottlingHandler()
|
||||
);
|
||||
|
||||
CosmosClient client = cosmosClientBuilder.Build();
|
||||
|
||||
DatabaseResponse databaseResponse = await client.CreateDatabaseIfNotExistsAsync("mydb");
|
||||
Database database = databaseResponse.Database;
|
||||
|
||||
ContainerResponse containerResponse = await database.CreateContainerIfNotExistsAsync("mycoll", "/id");
|
||||
Container container = containerResponse.Container;
|
||||
|
||||
Item item = new Item()
|
||||
{
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
Name = "Test Item",
|
||||
Description = "Some random test item",
|
||||
Completed = false
|
||||
};
|
||||
|
||||
// Create
|
||||
await container.CreateItemAsync<Item>(item, new PartitionKey(item.Id));
|
||||
|
||||
item.Completed = true;
|
||||
|
||||
// Replace
|
||||
await container.ReplaceItemAsync<Item>(item, item.Id, new PartitionKey(item.Id));
|
||||
|
||||
// Querying
|
||||
FeedIterator<Item> query = container.GetItemQueryIterator<Item>(new QueryDefinition("SELECT * FROM c"), requestOptions: new QueryRequestOptions() { MaxConcurrency = 1});
|
||||
List<Item> results = new List<Item>();
|
||||
while (query.HasMoreResults)
|
||||
{
|
||||
FeedResponse<Item> response = await query.ReadNextAsync();
|
||||
|
||||
results.AddRange(response.ToList());
|
||||
}
|
||||
|
||||
// Read Item
|
||||
|
||||
ItemResponse<Item> cosmosItemResponse = await container.ReadItemAsync<Item>(item.Id, new PartitionKey(item.Id));
|
||||
|
||||
ItemRequestOptions itemRequestOptions = new ItemRequestOptions()
|
||||
{
|
||||
IfMatchEtag = cosmosItemResponse.ETag
|
||||
};
|
||||
|
||||
// Concurrency
|
||||
|
||||
List<Task<ItemResponse<Item>>> tasks = new List<Task<ItemResponse<Item>>>
|
||||
{
|
||||
UpdateItemForConcurrency(container, itemRequestOptions, item),
|
||||
UpdateItemForConcurrency(container, itemRequestOptions, item)
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
await Task.WhenAll(tasks);
|
||||
}
|
||||
catch (CosmosException ex)
|
||||
{
|
||||
// Verify that our custom handler caught the scenario
|
||||
Debug.Assert(999.Equals(ex.SubStatusCode));
|
||||
}
|
||||
|
||||
// Delete
|
||||
await container.DeleteItemAsync<Item>(item.Id, new PartitionKey(item.Id));
|
||||
}
|
||||
// </Main>
|
||||
|
||||
// <UpdateItemForConcurrency>
|
||||
private static Task<ItemResponse<Item>> UpdateItemForConcurrency(Container container, ItemRequestOptions itemRequestOptions, Item item)
|
||||
{
|
||||
item.Description = $"Updating description {Guid.NewGuid().ToString()}";
|
||||
return container.ReplaceItemAsync<Item>(
|
||||
item,
|
||||
item.Id,
|
||||
new PartitionKey(item.Id),
|
||||
itemRequestOptions);
|
||||
}
|
||||
// </UpdateItemForConcurrency>
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
namespace Cosmos.Samples.Handlers
|
||||
{
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Azure.Cosmos;
|
||||
using Polly;
|
||||
|
||||
/// <summary>
|
||||
/// Using Polly to retry on Throttles.
|
||||
/// </summary>
|
||||
class ThrottlingHandler : RequestHandler
|
||||
{
|
||||
public override Task<ResponseMessage> SendAsync(
|
||||
RequestMessage request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
return Policy
|
||||
.HandleResult<ResponseMessage>(r => (int)r.StatusCode == 429)
|
||||
.RetryAsync(3)
|
||||
.ExecuteAsync(() => base.SendAsync(request, cancellationToken));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Shared\Shared.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\AppSettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,743 +0,0 @@
|
|||
namespace Cosmos.Samples.Shared
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Azure.Cosmos;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
// Prerequisites -
|
||||
//
|
||||
// 1. An Azure Cosmos account -
|
||||
// https://azure.microsoft.com/en-us/itemation/articles/itemdb-create-account/
|
||||
//
|
||||
// 2. Microsoft.Azure.Cosmos NuGet package -
|
||||
// http://www.nuget.org/packages/Microsoft.Azure.Cosmos/
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
// Sample - demonstrates the basic CRUD operations on a Item resource for Azure Cosmos
|
||||
//
|
||||
// 1. Basic CRUD operations on a item using regular POCOs
|
||||
// 1.1 - Create a item
|
||||
// 1.2 - Read a item by its Id
|
||||
// 1.3 - Read all items in a Collection
|
||||
// 1.4 - Query for items by a property other than Id
|
||||
// 1.5 - Replace a item
|
||||
// 1.6 - Upsert a item
|
||||
// 1.7 - Delete a item
|
||||
//
|
||||
// 2. Work with dynamic objects
|
||||
//
|
||||
// 3. Using ETags to control execution
|
||||
// 3.1 - Use ETag with ReplaceItem for optimistic concurrency
|
||||
// 3.2 - Use ETag with ReadItem to only return a result if the ETag of the request does not match
|
||||
//
|
||||
// 4 - Access items system defined properties
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
// See Also -
|
||||
//
|
||||
// Cosmos.Samples.Queries - We only included a VERY basic query here for completeness,
|
||||
// For a detailed exploration of how to query for Items,
|
||||
// including how to paginate results of queries.
|
||||
//
|
||||
// Cosmos.Samples.ServerSideScripts - In these examples we do simple loops to create small numbers
|
||||
// of items. For insert operations where you are creating many
|
||||
// items we recommend using a Stored Procedure and pass batches
|
||||
// of new items to this sproc. Consult this sample for an example
|
||||
// of a BulkInsert stored procedure.
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
|
||||
public class Program
|
||||
{
|
||||
private static readonly string databaseId = "samples";
|
||||
private static readonly string containerId = "item-samples";
|
||||
private static readonly JsonSerializer Serializer = new JsonSerializer();
|
||||
|
||||
//Reusable instance of ItemClient which represents the connection to a Cosmos endpoint
|
||||
private static Database database = null;
|
||||
private static Container container = null;
|
||||
|
||||
// Async main requires c# 7.1 which is set in the csproj with the LangVersion attribute
|
||||
// <Main>
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
IConfigurationRoot configuration = new ConfigurationBuilder()
|
||||
.AddJsonFile("appSettings.json")
|
||||
.Build();
|
||||
|
||||
string endpoint = configuration["EndPointUrl"];
|
||||
if (string.IsNullOrEmpty(endpoint))
|
||||
{
|
||||
throw new ArgumentNullException("Please specify a valid endpoint in the appSettings.json");
|
||||
}
|
||||
|
||||
string authKey = configuration["AuthorizationKey"];
|
||||
if (string.IsNullOrEmpty(authKey) || string.Equals(authKey, "Super secret key"))
|
||||
{
|
||||
throw new ArgumentException("Please specify a valid AuthorizationKey in the appSettings.json");
|
||||
}
|
||||
|
||||
//Read the Cosmos endpointUrl and authorisationKeys from configuration
|
||||
//These values are available from the Azure Management Portal on the Cosmos Account Blade under "Keys"
|
||||
//NB > Keep these values in a safe & secure location. Together they provide Administrative access to your Cosmos account
|
||||
using (CosmosClient client = new CosmosClient(endpoint, authKey))
|
||||
{
|
||||
await Program.Initialize(client);
|
||||
await Program.RunItemsDemo();
|
||||
await Program.Cleanup();
|
||||
}
|
||||
}
|
||||
catch (CosmosException cre)
|
||||
{
|
||||
Console.WriteLine(cre.ToString());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Exception baseException = e.GetBaseException();
|
||||
Console.WriteLine("Error: {0}, Message: {1}", e.Message, baseException.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (Debugger.IsAttached)
|
||||
{
|
||||
Console.WriteLine("End of demo, press any key to exit.");
|
||||
Console.ReadKey();
|
||||
}
|
||||
}
|
||||
}
|
||||
// </Main>
|
||||
|
||||
/// <summary>
|
||||
/// Run basic item access methods as a console app demo
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
// <RunItemsDemo>
|
||||
private static async Task RunItemsDemo()
|
||||
{
|
||||
await Program.RunBasicOperationsOnStronglyTypedObjects();
|
||||
|
||||
await Program.RunBasicOperationsOnDynamicObjects();
|
||||
|
||||
await Program.UseETags();
|
||||
|
||||
await Program.UseConsistencyLevels();
|
||||
|
||||
await Program.AccessSystemDefinedProperties();
|
||||
}
|
||||
// </RunItemsDemo>
|
||||
|
||||
/// <summary>
|
||||
/// 1. Basic CRUD operations on a item
|
||||
/// 1.1 - Create a item
|
||||
/// 1.2 - Read a item by its Id
|
||||
/// 1.3 - Read all items in a Collection
|
||||
/// 1.4 - Query for items by a property other than Id
|
||||
/// 1.5 - Replace a item
|
||||
/// 1.6 - Upsert a item
|
||||
/// 1.7 - Delete a item
|
||||
/// </summary>
|
||||
// <RunBasicOperationsOnStronglyTypedObjects>
|
||||
private static async Task RunBasicOperationsOnStronglyTypedObjects()
|
||||
{
|
||||
SalesOrder result = await Program.CreateItemsAsync();
|
||||
|
||||
await Program.ReadItemAsync();
|
||||
|
||||
await Program.QueryItems();
|
||||
|
||||
await Program.ReplaceItemAsync(result);
|
||||
|
||||
await Program.UpsertItemAsync();
|
||||
|
||||
await Program.DeleteItemAsync();
|
||||
}
|
||||
// </RunBasicOperationsOnStronglyTypedObjects>
|
||||
|
||||
// <CreateItemsAsync>
|
||||
private static async Task<SalesOrder> CreateItemsAsync()
|
||||
{
|
||||
Console.WriteLine("\n1.1 - Creating items");
|
||||
|
||||
// Create a SalesOrder object. This object has nested properties and various types including numbers, DateTimes and strings.
|
||||
// This can be saved as JSON as is without converting into rows/columns.
|
||||
SalesOrder salesOrder = GetSalesOrderSample("SalesOrder1");
|
||||
ItemResponse<SalesOrder> response = await container.CreateItemAsync(salesOrder, new PartitionKey(salesOrder.AccountNumber));
|
||||
SalesOrder salesOrder1 = response;
|
||||
Console.WriteLine($"\n1.1.1 - Item created {salesOrder1.Id}");
|
||||
|
||||
// As your app evolves, let's say your object has a new schema. You can insert SalesOrderV2 objects without any
|
||||
// changes to the database tier.
|
||||
SalesOrder2 newSalesOrder = GetSalesOrderV2Sample("SalesOrder2");
|
||||
ItemResponse<SalesOrder2> response2 = await container.CreateItemAsync(newSalesOrder, new PartitionKey(newSalesOrder.AccountNumber));
|
||||
SalesOrder2 salesOrder2 = response2;
|
||||
Console.WriteLine($"\n1.1.2 - Item created {salesOrder2.Id}");
|
||||
|
||||
// For better performance create a SalesOrder object from a stream.
|
||||
SalesOrder salesOrderV3 = GetSalesOrderSample("SalesOrderV3");
|
||||
using (Stream stream = Program.ToStream<SalesOrder>(salesOrderV3))
|
||||
{
|
||||
using (ResponseMessage responseMessage = await container.CreateItemStreamAsync(stream, new PartitionKey(salesOrderV3.AccountNumber)))
|
||||
{
|
||||
// Item stream operations do not throw exceptions for better performance
|
||||
if (responseMessage.IsSuccessStatusCode)
|
||||
{
|
||||
SalesOrder streamResponse = FromStream<SalesOrder>(responseMessage.Content);
|
||||
Console.WriteLine($"\n1.1.2 - Item created {streamResponse.Id}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Create item from stream failed. Status code: {responseMessage.StatusCode} Message: {responseMessage.ErrorMessage}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return salesOrder;
|
||||
}
|
||||
// </CreateItemsAsync>
|
||||
|
||||
// <ReadItemAsync>
|
||||
private static async Task ReadItemAsync()
|
||||
{
|
||||
Console.WriteLine("\n1.2 - Reading Item by Id");
|
||||
|
||||
// Note that Reads require a partition key to be specified.
|
||||
ItemResponse<SalesOrder> response = await container.ReadItemAsync<SalesOrder>(
|
||||
partitionKey: new PartitionKey("Account1"),
|
||||
id: "SalesOrder1");
|
||||
|
||||
// You can measure the throughput consumed by any operation by inspecting the RequestCharge property
|
||||
Console.WriteLine("Item read by Id {0}", response.Resource);
|
||||
Console.WriteLine("Request Units Charge for reading a Item by Id {0}", response.RequestCharge);
|
||||
|
||||
SalesOrder readOrder = (SalesOrder)response;
|
||||
|
||||
// Read the same item but as a stream.
|
||||
using (ResponseMessage responseMessage = await container.ReadItemStreamAsync(
|
||||
partitionKey: new PartitionKey("Account1"),
|
||||
id: "SalesOrder1"))
|
||||
{
|
||||
// Item stream operations do not throw exceptions for better performance
|
||||
if (responseMessage.IsSuccessStatusCode)
|
||||
{
|
||||
SalesOrder streamResponse = FromStream<SalesOrder>(responseMessage.Content);
|
||||
Console.WriteLine($"\n1.2.2 - Item created {streamResponse.Id}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Read item from stream failed. Status code: {responseMessage.StatusCode} Message: {responseMessage.ErrorMessage}");
|
||||
}
|
||||
}
|
||||
}
|
||||
// </ReadItemAsync>
|
||||
|
||||
// <QueryItems>
|
||||
private static async Task QueryItems()
|
||||
{
|
||||
//******************************************************************************************************************
|
||||
// 1.4 - Query for items by a property other than Id
|
||||
//
|
||||
// NOTE: Operations like AsEnumerable(), ToList(), ToArray() will make as many trips to the database
|
||||
// as required to fetch the entire result-set. Even if you set MaxItemCount to a smaller number.
|
||||
// MaxItemCount just controls how many results to fetch each trip.
|
||||
//******************************************************************************************************************
|
||||
Console.WriteLine("\n1.4 - Querying for a item using its AccountNumber property");
|
||||
|
||||
QueryDefinition query = new QueryDefinition(
|
||||
"select * from sales s where s.AccountNumber = @AccountInput ")
|
||||
.WithParameter("@AccountInput", "Account1");
|
||||
|
||||
FeedIterator<SalesOrder> resultSet = container.GetItemQueryIterator<SalesOrder>(
|
||||
query,
|
||||
requestOptions: new QueryRequestOptions()
|
||||
{
|
||||
PartitionKey = new PartitionKey("Account1"),
|
||||
MaxItemCount = 1
|
||||
});
|
||||
|
||||
List<SalesOrder> allSalesForAccount1 = new List<SalesOrder>();
|
||||
while (resultSet.HasMoreResults)
|
||||
{
|
||||
SalesOrder sale = (await resultSet.ReadNextAsync()).First();
|
||||
Console.WriteLine($"\n1.4.1 Account Number: {sale.AccountNumber}; Id: {sale.Id} ");
|
||||
allSalesForAccount1.Add(sale);
|
||||
}
|
||||
|
||||
Console.WriteLine($"\n1.4.2 Query found {allSalesForAccount1.Count} items.");
|
||||
|
||||
// Use the same query as before but get the cosmos response message to access the stream directly
|
||||
FeedIterator streamResultSet = container.GetItemQueryStreamIterator(
|
||||
query,
|
||||
requestOptions: new QueryRequestOptions()
|
||||
{
|
||||
PartitionKey = new PartitionKey("Account1"),
|
||||
MaxItemCount = 10,
|
||||
MaxConcurrency = 1
|
||||
});
|
||||
|
||||
List<SalesOrder> allSalesForAccount1FromStream = new List<SalesOrder>();
|
||||
while (streamResultSet.HasMoreResults)
|
||||
{
|
||||
using (ResponseMessage responseMessage = await streamResultSet.ReadNextAsync())
|
||||
{
|
||||
// Item stream operations do not throw exceptions for better performance
|
||||
if (responseMessage.IsSuccessStatusCode)
|
||||
{
|
||||
dynamic streamResponse = FromStream<dynamic>(responseMessage.Content);
|
||||
List<SalesOrder> salesOrders = streamResponse.Documents.ToObject<List<SalesOrder>>();
|
||||
Console.WriteLine($"\n1.4.3 - Item Query via stream {salesOrders.Count}");
|
||||
allSalesForAccount1FromStream.AddRange(salesOrders);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Query item from stream failed. Status code: {responseMessage.StatusCode} Message: {responseMessage.ErrorMessage}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine($"\n1.4.4 Query found {allSalesForAccount1FromStream.Count} items.");
|
||||
|
||||
if (allSalesForAccount1.Count != allSalesForAccount1FromStream.Count)
|
||||
{
|
||||
throw new InvalidDataException($"Both query operations should return the same list");
|
||||
}
|
||||
}
|
||||
// </QueryItems>
|
||||
|
||||
// <ReplaceItemAsync>
|
||||
private static async Task ReplaceItemAsync(SalesOrder order)
|
||||
{
|
||||
//******************************************************************************************************************
|
||||
// 1.5 - Replace a item
|
||||
//
|
||||
// Just update a property on an existing item and issue a Replace command
|
||||
//******************************************************************************************************************
|
||||
Console.WriteLine("\n1.5 - Replacing a item using its Id");
|
||||
|
||||
order.ShippedDate = DateTime.UtcNow;
|
||||
ItemResponse<SalesOrder> response = await container.ReplaceItemAsync(
|
||||
partitionKey: new PartitionKey(order.AccountNumber),
|
||||
id: order.Id,
|
||||
item: order);
|
||||
|
||||
SalesOrder updated = response.Resource;
|
||||
Console.WriteLine($"Request charge of replace operation: {response.RequestCharge}");
|
||||
Console.WriteLine($"Shipped date of updated item: {updated.ShippedDate}");
|
||||
|
||||
order.ShippedDate = DateTime.UtcNow;
|
||||
using (Stream stream = Program.ToStream<SalesOrder>(order))
|
||||
{
|
||||
using (ResponseMessage responseMessage = await container.ReplaceItemStreamAsync(
|
||||
partitionKey: new PartitionKey(order.AccountNumber),
|
||||
id: order.Id,
|
||||
streamPayload: stream))
|
||||
{
|
||||
// Item stream operations do not throw exceptions for better performance
|
||||
if (responseMessage.IsSuccessStatusCode)
|
||||
{
|
||||
SalesOrder streamResponse = FromStream<SalesOrder>(responseMessage.Content);
|
||||
Console.WriteLine($"\n1.5.2 - Item replace via stream {streamResponse.Id}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Replace item from stream failed. Status code: {responseMessage.StatusCode} Message: {responseMessage.ErrorMessage}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// </ReplaceItemAsync>
|
||||
|
||||
// <UpsertItemAsync>
|
||||
private static async Task UpsertItemAsync()
|
||||
{
|
||||
Console.WriteLine("\n1.6 - Upserting a item");
|
||||
|
||||
SalesOrder upsertOrder = GetSalesOrderSample("SalesOrder3");
|
||||
ItemResponse<SalesOrder> response = await container.UpsertItemAsync(
|
||||
partitionKey: new PartitionKey(upsertOrder.AccountNumber),
|
||||
item: upsertOrder);
|
||||
|
||||
SalesOrder upserted = response.Resource;
|
||||
Console.WriteLine($"Request charge of upsert operation: {response.RequestCharge}");
|
||||
Console.WriteLine($"StatusCode of this operation: { response.StatusCode}");
|
||||
Console.WriteLine($"Id of upserted item: {upserted.Id}");
|
||||
Console.WriteLine($"AccountNumber of upserted item: {upserted.AccountNumber}");
|
||||
|
||||
upserted.AccountNumber = "updated account number";
|
||||
response = await container.UpsertItemAsync(partitionKey: new PartitionKey(upserted.AccountNumber), item: upserted);
|
||||
upserted = response.Resource;
|
||||
|
||||
Console.WriteLine($"Request charge of upsert operation: {response.RequestCharge}");
|
||||
Console.WriteLine($"StatusCode of this operation: { response.StatusCode}");
|
||||
Console.WriteLine($"Id of upserted item: {upserted.Id}");
|
||||
Console.WriteLine($"AccountNumber of upserted item: {upserted.AccountNumber}");
|
||||
|
||||
// For better performance upsert a SalesOrder object from a stream.
|
||||
SalesOrder salesOrderV4 = GetSalesOrderSample("SalesOrder4");
|
||||
using (Stream stream = Program.ToStream<SalesOrder>(salesOrderV4))
|
||||
{
|
||||
using (ResponseMessage responseMessage = await container.UpsertItemStreamAsync(
|
||||
partitionKey: new PartitionKey(salesOrderV4.AccountNumber),
|
||||
streamPayload: stream))
|
||||
{
|
||||
// Item stream operations do not throw exceptions for better performance
|
||||
if (responseMessage.IsSuccessStatusCode)
|
||||
{
|
||||
SalesOrder streamResponse = FromStream<SalesOrder>(responseMessage.Content);
|
||||
Console.WriteLine($"\n1.6.2 - Item upserted via stream {streamResponse.Id}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Upsert item from stream failed. Status code: {responseMessage.StatusCode} Message: {responseMessage.ErrorMessage}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// </UpsertItemAsync>
|
||||
|
||||
// <DeleteItemAsync>
|
||||
private static async Task DeleteItemAsync()
|
||||
{
|
||||
Console.WriteLine("\n1.7 - Deleting a item");
|
||||
ItemResponse<SalesOrder> response = await container.DeleteItemAsync<SalesOrder>(
|
||||
partitionKey: new PartitionKey("Account1"),
|
||||
id: "SalesOrder3");
|
||||
|
||||
Console.WriteLine("Request charge of delete operation: {0}", response.RequestCharge);
|
||||
Console.WriteLine("StatusCode of operation: {0}", response.StatusCode);
|
||||
}
|
||||
// </DeleteItemAsync>
|
||||
|
||||
private static T FromStream<T>(Stream stream)
|
||||
{
|
||||
using (stream)
|
||||
{
|
||||
if (typeof(Stream).IsAssignableFrom(typeof(T)))
|
||||
{
|
||||
return (T)(object)(stream);
|
||||
}
|
||||
|
||||
using (StreamReader sr = new StreamReader(stream))
|
||||
{
|
||||
using (JsonTextReader jsonTextReader = new JsonTextReader(sr))
|
||||
{
|
||||
return Program.Serializer.Deserialize<T>(jsonTextReader);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Stream ToStream<T>(T input)
|
||||
{
|
||||
MemoryStream streamPayload = new MemoryStream();
|
||||
using (StreamWriter streamWriter = new StreamWriter(streamPayload, encoding: Encoding.Default, bufferSize: 1024, leaveOpen: true))
|
||||
{
|
||||
using (JsonWriter writer = new JsonTextWriter(streamWriter))
|
||||
{
|
||||
writer.Formatting = Newtonsoft.Json.Formatting.None;
|
||||
Program.Serializer.Serialize(writer, input);
|
||||
writer.Flush();
|
||||
streamWriter.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
streamPayload.Position = 0;
|
||||
return streamPayload;
|
||||
}
|
||||
|
||||
private static SalesOrder GetSalesOrderSample(string itemId)
|
||||
{
|
||||
SalesOrder salesOrder = new SalesOrder
|
||||
{
|
||||
Id = itemId,
|
||||
AccountNumber = "Account1",
|
||||
PurchaseOrderNumber = "PO18009186470",
|
||||
OrderDate = new DateTime(2005, 7, 1),
|
||||
SubTotal = 419.4589m,
|
||||
TaxAmount = 12.5838m,
|
||||
Freight = 472.3108m,
|
||||
TotalDue = 985.018m,
|
||||
Items = new SalesOrderDetail[]
|
||||
{
|
||||
new SalesOrderDetail
|
||||
{
|
||||
OrderQty = 1,
|
||||
ProductId = 760,
|
||||
UnitPrice = 419.4589m,
|
||||
LineTotal = 419.4589m
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// Set the "ttl" property to auto-expire sales orders in 30 days
|
||||
salesOrder.TimeToLive = 60 * 60 * 24 * 30;
|
||||
|
||||
return salesOrder;
|
||||
}
|
||||
|
||||
private static SalesOrder2 GetSalesOrderV2Sample(string itemId)
|
||||
{
|
||||
return new SalesOrder2
|
||||
{
|
||||
Id = itemId,
|
||||
AccountNumber = "Account2",
|
||||
PurchaseOrderNumber = "PO15428132599",
|
||||
OrderDate = new DateTime(2005, 7, 1),
|
||||
DueDate = new DateTime(2005, 7, 13),
|
||||
ShippedDate = new DateTime(2005, 7, 8),
|
||||
SubTotal = 6107.0820m,
|
||||
TaxAmt = 586.1203m,
|
||||
Freight = 183.1626m,
|
||||
DiscountAmt = 1982.872m, // new property added to SalesOrder2
|
||||
TotalDue = 4893.3929m,
|
||||
Items = new SalesOrderDetail2[]
|
||||
{
|
||||
new SalesOrderDetail2
|
||||
{
|
||||
OrderQty = 3,
|
||||
ProductCode = "A-123", // notice how in SalesOrderDetail2 we no longer reference a ProductId
|
||||
ProductName = "Product 1", // instead we have decided to denormalize our schema and include
|
||||
CurrencySymbol = "$", // the Product details relevant to the Order on to the Order directly
|
||||
CurrencyCode = "USD", // this is a typical refactor that happens in the course of an application
|
||||
UnitPrice = 17.1m, // that would have previously required schema changes and data migrations etc.
|
||||
LineTotal = 5.7m
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 2. Basic CRUD operations using dynamics instead of strongly typed objects
|
||||
/// Cosmos does not require objects to be typed. Applications that merge data from different data sources, or
|
||||
/// need to handle evolving schemas can write data directly as JSON or dynamic objects.
|
||||
/// </summary>
|
||||
// <RunBasicOperationsOnDynamicObjects>
|
||||
private static async Task RunBasicOperationsOnDynamicObjects()
|
||||
{
|
||||
Console.WriteLine("\n2. Use Dynamics");
|
||||
|
||||
// Create a dynamic object
|
||||
dynamic salesOrder = new
|
||||
{
|
||||
id = "_SalesOrder5",
|
||||
AccountNumber = "NewUser01",
|
||||
PurchaseOrderNumber = "PO18009186470",
|
||||
OrderDate = DateTime.UtcNow,
|
||||
Total = 5.95,
|
||||
};
|
||||
|
||||
Console.WriteLine("\nCreating item");
|
||||
|
||||
ItemResponse<dynamic> response = await container.CreateItemAsync<dynamic>(salesOrder, new PartitionKey("NewUser01"));
|
||||
dynamic createdItem = response.Resource;
|
||||
|
||||
Console.WriteLine("Item with id {0} created", createdItem.Id);
|
||||
Console.WriteLine("Request charge of operation: {0}", response.RequestCharge);
|
||||
|
||||
response = await container.ReadItemAsync<dynamic>(partitionKey: new PartitionKey("NewUser01"), id: "_SalesOrder5");
|
||||
|
||||
dynamic readItem = response.Resource;
|
||||
|
||||
//update a dynamic object by just creating a new Property on the fly
|
||||
//Item is itself a dynamic object, so you can just use this directly too if you prefer
|
||||
readItem.Add("shippedDate", DateTime.UtcNow);
|
||||
|
||||
//if you wish to work with a dynamic object so you don't need to use SetPropertyValue() or GetPropertyValue<T>()
|
||||
//then you can cast to a dynamic
|
||||
salesOrder = readItem;
|
||||
salesOrder.foo = "bar";
|
||||
|
||||
//now do a replace using this dynamic item
|
||||
//everything that is needed is contained in the readDynOrder object
|
||||
//it has a .self Property
|
||||
Console.WriteLine("\nReplacing item");
|
||||
|
||||
response = await container.ReplaceItemAsync<dynamic>(partitionKey: new PartitionKey("NewUser01"), id: "_SalesOrder5", item: salesOrder);
|
||||
dynamic replaced = response.Resource;
|
||||
|
||||
Console.WriteLine("Request charge of operation: {0}", response.RequestCharge);
|
||||
Console.WriteLine("shippedDate: {0} and foo: {1} of replaced item", replaced.shippedDate, replaced.foo);
|
||||
}
|
||||
// </RunBasicOperationsOnDynamicObjects>
|
||||
|
||||
/// <summary>
|
||||
/// 3. Using ETags to control execution of operations
|
||||
/// 3.1 - Use ETag to control if a ReplaceItem operation should check if ETag of request matches Item
|
||||
/// 3.2 - Use ETag to control if ReadItem should only return a result if the ETag of the request does not match the Item
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
// <UseETags>
|
||||
private static async Task UseETags()
|
||||
{
|
||||
//******************************************************************************************************************
|
||||
// 3.1 - Use ETag to control if a replace should succeed, or not, based on whether the ETag on the request matches
|
||||
// the current ETag value of the persisted Item
|
||||
//
|
||||
// All items in Cosmos have an _etag field. This gets set on the server every time a item is updated.
|
||||
//
|
||||
// When doing a replace of a item you can opt-in to having the server only apply the Replace if the ETag
|
||||
// on the request matches the ETag of the item on the server.
|
||||
// If someone did an update to the same item since you read it, then the ETag on the server will not match
|
||||
// and the Replace operation can be rejected.
|
||||
//******************************************************************************************************************
|
||||
Console.WriteLine("\n3.1 - Using optimistic concurrency when doing a ReplaceItemAsync");
|
||||
|
||||
//read a item
|
||||
ItemResponse<SalesOrder> itemResponse = await container.ReadItemAsync<SalesOrder>(
|
||||
partitionKey: new PartitionKey("Account1"),
|
||||
id: "SalesOrder1");
|
||||
|
||||
Console.WriteLine("ETag of read item - {0}", itemResponse.ETag);
|
||||
|
||||
SalesOrder item = itemResponse;
|
||||
//Update the total due
|
||||
itemResponse.Resource.TotalDue = 1000000;
|
||||
|
||||
//persist the change back to the server
|
||||
ItemResponse<SalesOrder> updatedDoc = await container.ReplaceItemAsync<SalesOrder>(
|
||||
partitionKey: new PartitionKey(item.AccountNumber),
|
||||
id: item.Id,
|
||||
item: item);
|
||||
|
||||
Console.WriteLine("ETag of item now that is has been updated - {0}", updatedDoc.ETag);
|
||||
|
||||
//now, using the originally retrieved item do another update
|
||||
//but set the AccessCondition class with the ETag of the originally read item and also set the AccessConditionType
|
||||
//this tells the service to only do this operation if ETag on the request matches the current ETag on the item
|
||||
//in our case it won't, because we updated the item and therefore gave it a new ETag
|
||||
try
|
||||
{
|
||||
itemResponse.Resource.TotalDue = 9999999;
|
||||
updatedDoc = await container.ReplaceItemAsync<SalesOrder>(itemResponse, item.Id, new PartitionKey(item.AccountNumber), new ItemRequestOptions { IfMatchEtag = itemResponse.ETag });
|
||||
}
|
||||
catch (CosmosException cre)
|
||||
{
|
||||
// now notice the failure when attempting the update
|
||||
// this is because the ETag on the server no longer matches the ETag of doc (b/c it was changed in step 2)
|
||||
if (cre.StatusCode == HttpStatusCode.PreconditionFailed)
|
||||
{
|
||||
Console.WriteLine("As expected, we have a pre-condition failure exception\n");
|
||||
}
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
// 3.2 - ETag on a ReadItemAsync request can be used to tell the server whether it should return a result, or not
|
||||
//
|
||||
// By setting the ETag on a ReadItemRequest along with an AccessCondition of IfNoneMatch instructs the server
|
||||
// to only return a result if the ETag of the request does not match that of the persisted Item
|
||||
//*******************************************************************************************************************
|
||||
|
||||
Console.WriteLine("\n3.2 - Using ETag to do a conditional ReadItemAsync");
|
||||
|
||||
// Get a item
|
||||
ItemResponse<SalesOrder> response = await container.ReadItemAsync<SalesOrder>(partitionKey: new PartitionKey("Account2"), id: "SalesOrder2");
|
||||
|
||||
item = response;
|
||||
Console.WriteLine($"Read doc with StatusCode of {response.StatusCode}");
|
||||
|
||||
// Get the item again with conditional access set, no item should be returned
|
||||
response = await container.ReadItemAsync<SalesOrder>(
|
||||
partitionKey: new PartitionKey("Account2"),
|
||||
id: "SalesOrder2",
|
||||
requestOptions: new ItemRequestOptions() { IfNoneMatchEtag = itemResponse.ETag });
|
||||
|
||||
Console.WriteLine("Read doc with StatusCode of {0}", response.StatusCode);
|
||||
|
||||
// Now change something on the item, then do another get and this time we should get the item back
|
||||
response.Resource.TotalDue = 42;
|
||||
|
||||
response = await container.ReplaceItemAsync<SalesOrder>(item, item.Id, new PartitionKey(item.AccountNumber));
|
||||
|
||||
response = await container.ReadItemAsync<SalesOrder>(
|
||||
partitionKey: new PartitionKey("Account2"),
|
||||
id: "SalesOrder2",
|
||||
requestOptions: new ItemRequestOptions() { IfNoneMatchEtag = itemResponse.ETag });
|
||||
|
||||
|
||||
Console.WriteLine("Read doc with StatusCode of {0}", response.StatusCode);
|
||||
}
|
||||
// </UseETags>
|
||||
|
||||
/// <summary>
|
||||
/// 4. Access items system defined properties
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
// <AccessSystemDefinedProperties>
|
||||
private static async Task AccessSystemDefinedProperties()
|
||||
{
|
||||
//******************************************************************************************************************
|
||||
// Items contain attributes that are system defined:
|
||||
// Timestamp : Gets the last modified timestamp associated with the item from the Azure Cosmos DB service.
|
||||
// Etag : Gets the entity tag associated with the item from the Azure Cosmos DB service.
|
||||
// TimeToLive : Gets the time to live in seconds of the item in the Azure Cosmos DB service.
|
||||
//
|
||||
// See also: https://docs.microsoft.com/azure/cosmos-db/databases-containers-items#azure-cosmos-containers
|
||||
//******************************************************************************************************************
|
||||
Console.WriteLine("\n4 - Accessing system defined properties");
|
||||
|
||||
//read a item's metadata
|
||||
|
||||
Metadata itemResponse = await container.ReadItemAsync<Metadata>(
|
||||
partitionKey: new PartitionKey("Account1"),
|
||||
id: "SalesOrder1");
|
||||
|
||||
Console.WriteLine("ETag of read item - {0}", itemResponse.Etag);
|
||||
|
||||
Console.WriteLine("TimeToLive of read item - {0}", itemResponse.TimeToLive);
|
||||
|
||||
Console.WriteLine("Timestamp of read item - {0}", itemResponse.Timestamp.ToShortDateString());
|
||||
}
|
||||
// </AccessSystemDefinedProperties>
|
||||
|
||||
// <UseConsistencyLevels>
|
||||
private static async Task UseConsistencyLevels()
|
||||
|
||||
{
|
||||
// Override the consistency level for a read request
|
||||
ItemResponse<SalesOrder> response = await container.ReadItemAsync<SalesOrder>(
|
||||
partitionKey: new PartitionKey("Account2"),
|
||||
id: "SalesOrder2",
|
||||
requestOptions: new ItemRequestOptions() { ConsistencyLevel = ConsistencyLevel.Eventual });
|
||||
}
|
||||
// </UseConsistencyLevels>
|
||||
|
||||
private static async Task Cleanup()
|
||||
{
|
||||
if (database != null)
|
||||
{
|
||||
await database.DeleteAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task Initialize(CosmosClient client)
|
||||
{
|
||||
database = await client.CreateDatabaseIfNotExistsAsync(databaseId);
|
||||
|
||||
// Delete the existing container to prevent create item conflicts
|
||||
using (await database.GetContainer(containerId).DeleteContainerStreamAsync())
|
||||
{ }
|
||||
|
||||
// We create a partitioned collection here which needs a partition key. Partitioned collections
|
||||
// can be created with very high values of provisioned throughput (up to Throughput = 250,000)
|
||||
// and used to store up to 250 GB of data. You can also skip specifying a partition key to create
|
||||
// single partition collections that store up to 10 GB of data.
|
||||
// For this demo, we create a collection to store SalesOrders. We set the partition key to the account
|
||||
// number so that we can retrieve all sales orders for an account efficiently from a single partition,
|
||||
// and perform transactions across multiple sales order for a single account number.
|
||||
ContainerProperties containerProperties = new ContainerProperties(containerId, partitionKeyPath: "/AccountNumber");
|
||||
|
||||
// Create with a throughput of 1000 RU/s
|
||||
container = await database.CreateContainerIfNotExistsAsync(
|
||||
containerProperties,
|
||||
throughput: 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Shared\Shared.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\AppSettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,337 +0,0 @@
|
|||
namespace Cosmos.Samples.Shared
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Azure.Cosmos;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
/// <summary>
|
||||
/// ----------------------------------------------------------------------------------------------------------
|
||||
/// Prerequisites -
|
||||
///
|
||||
/// 1. An Azure Cosmos account -
|
||||
/// https://azure.microsoft.com/en-us/itemation/articles/itemdb-create-account/
|
||||
///
|
||||
/// 2. Microsoft.Azure.Cosmos NuGet package -
|
||||
/// http://www.nuget.org/packages/Microsoft.Azure.Cosmos/
|
||||
/// ----------------------------------------------------------------------------------------------------------
|
||||
/// Sample - Demonstrates the basic CRUD operations on Container that is migrated from Non-Partitioned mode to
|
||||
/// Partitioned mode.
|
||||
///
|
||||
/// These include the following operations:
|
||||
/// 1. Document CRUD operations in the same logical partition as pre-migration
|
||||
/// 2. Document CRUD operations with a partition key value on the migrated container
|
||||
/// 3. Migration of documents inserted without partition key into a logical parition with a valid partition key value
|
||||
///
|
||||
///
|
||||
/// Note: This sample is written for V3 SDK and since V3 SDK doesn't allow creating a container without partition key,
|
||||
/// this sample uses REST API to perform such operation.
|
||||
/// ----------------------------------------------------------------------------------------------------------
|
||||
/// </summary>
|
||||
|
||||
public class Program
|
||||
{
|
||||
private static readonly string PreNonPartitionedMigrationApiVersion = "2018-09-17";
|
||||
private static readonly string utc_date = DateTime.UtcNow.ToString("r");
|
||||
private static readonly JsonSerializer Serializer = new JsonSerializer();
|
||||
|
||||
private static string databaseId = null;
|
||||
private static string containerId = null;
|
||||
|
||||
public class DeviceInformationItem
|
||||
{
|
||||
[JsonProperty(PropertyName = "id")]
|
||||
public string Id { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "deviceId")]
|
||||
public string DeviceId { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "_partitionKey", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string PartitionKey { get; set; }
|
||||
}
|
||||
|
||||
// <Main>
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
databaseId = "deviceInformation" + Guid.NewGuid().ToString();
|
||||
containerId = "device-samples" + Guid.NewGuid().ToString();
|
||||
|
||||
IConfigurationRoot configuration = new ConfigurationBuilder()
|
||||
.AddJsonFile("appSettings.json")
|
||||
.Build();
|
||||
|
||||
string endpoint = configuration["EndPointUrl"];
|
||||
if (string.IsNullOrEmpty(endpoint))
|
||||
{
|
||||
throw new ArgumentNullException("Please specify a valid endpoint in the appSettings.json");
|
||||
}
|
||||
|
||||
string authKey = configuration["AuthorizationKey"];
|
||||
if (string.IsNullOrEmpty(authKey) || string.Equals(authKey, "Super secret key"))
|
||||
{
|
||||
throw new ArgumentException("Please specify a valid AuthorizationKey in the appSettings.json");
|
||||
}
|
||||
|
||||
using (CosmosClient client = new CosmosClient(endpoint, authKey))
|
||||
{
|
||||
Database database = await client.CreateDatabaseIfNotExistsAsync(databaseId);
|
||||
|
||||
// Create the container using REST API without a partition key definition
|
||||
await Program.CreateNonPartitionedContainerAsync(endpoint, authKey);
|
||||
|
||||
Container container = database.GetContainer(containerId);
|
||||
|
||||
// Read back the same container and verify that partition key path is populated
|
||||
// Partition key is returned when read from V3 SDK.
|
||||
ContainerResponse containerResposne = await container.ReadContainerAsync();
|
||||
if (containerResposne.Resource.PartitionKeyPath != null)
|
||||
{
|
||||
Console.WriteLine("Container Partition Key path {0}", containerResposne.Resource.PartitionKeyPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Unexpected error : Partition Key is not populated in a migrated collection");
|
||||
}
|
||||
|
||||
Console.WriteLine("--Demo Item operations with no partition key--");
|
||||
await Program.ItemOperationsWithNonePartitionKeyValue(container);
|
||||
|
||||
Console.WriteLine("--Demo Item operations with valid partition key--");
|
||||
await Program.ItemOperationsWithValidPartitionKeyValue(container);
|
||||
|
||||
Console.WriteLine("--Demo migration of items inserted with no partition key to items with a partition key--");
|
||||
await Program.MigratedItemsFromNonePartitionKeyToValidPartitionKeyValue(container);
|
||||
|
||||
// Clean up the database -- for rerunning the sample
|
||||
await database.DeleteAsync();
|
||||
}
|
||||
}
|
||||
catch (CosmosException cre)
|
||||
{
|
||||
Console.WriteLine(cre.ToString());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Exception baseException = e.GetBaseException();
|
||||
Console.WriteLine("Error: {0}, Message: {1}", e.Message, baseException.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.WriteLine("End of demo, press any key to exit.");
|
||||
Console.ReadKey();
|
||||
}
|
||||
}
|
||||
// </Main>
|
||||
|
||||
/// <summary>
|
||||
/// The function demonstrates the Item CRUD operation using the NonePartitionKeyValue
|
||||
/// NonePartitionKeyValue represents the information that the current item doesn't have a value for partitition key
|
||||
/// All items inserted pre-migration are grouped into this logical partition and can be accessed by providing this value
|
||||
/// for the partitionKey parameter
|
||||
/// New item CRUD could be performed using this NonePartitionKeyValue to target the same logical partition
|
||||
/// </summary>
|
||||
// <ItemOperationsWithNonePartitionKeyValue>
|
||||
private static async Task ItemOperationsWithNonePartitionKeyValue(Container container)
|
||||
{
|
||||
string itemid = Guid.NewGuid().ToString();
|
||||
DeviceInformationItem itemWithoutPK = GetDeviceWithNoPartitionKey(itemid);
|
||||
|
||||
// Insert a new item with NonePartitionKeyValue
|
||||
ItemResponse<DeviceInformationItem> createResponse = await container.CreateItemAsync<DeviceInformationItem>(
|
||||
item: itemWithoutPK,
|
||||
partitionKey: PartitionKey.None);
|
||||
Console.WriteLine("Creating Item {0} Status Code {1}", itemid, createResponse.StatusCode);
|
||||
|
||||
// Read an existing item with NonePartitionKeyValue
|
||||
ItemResponse<DeviceInformationItem> readResponse = await container.ReadItemAsync<DeviceInformationItem>(
|
||||
id: itemid,
|
||||
partitionKey: PartitionKey.None
|
||||
);
|
||||
Console.WriteLine("Reading Item {0} Status Code {1}", itemid, readResponse.StatusCode);
|
||||
|
||||
// Replace the content of existing item with NonePartitionKeyValue
|
||||
itemWithoutPK.DeviceId = Guid.NewGuid().ToString();
|
||||
ItemResponse<DeviceInformationItem> replaceResponse = await container.ReplaceItemAsync<DeviceInformationItem>(
|
||||
item: itemWithoutPK,
|
||||
id: itemWithoutPK.Id,
|
||||
partitionKey: PartitionKey.None
|
||||
);
|
||||
Console.WriteLine("Replacing Item {0} Status Code {1}", itemid, replaceResponse.StatusCode);
|
||||
|
||||
// Delete an item with NonePartitionKeyValue.
|
||||
ItemResponse<DeviceInformationItem> deleteResponse = await container.DeleteItemAsync<DeviceInformationItem>(
|
||||
id: itemid,
|
||||
partitionKey: PartitionKey.None
|
||||
);
|
||||
Console.WriteLine("Deleting Item {0} Status Code {1}", itemid, deleteResponse.StatusCode);
|
||||
}
|
||||
// </ItemOperationsWithNonePartitionKeyValue>
|
||||
|
||||
/// <summary>
|
||||
/// The function demonstrates CRUD operations on the migrated collection supplying a value for the partition key
|
||||
/// <summary>
|
||||
// <ItemOperationsWithValidPartitionKeyValue>
|
||||
private static async Task ItemOperationsWithValidPartitionKeyValue(Container container)
|
||||
{
|
||||
string itemid = Guid.NewGuid().ToString();
|
||||
string partitionKey = "a";
|
||||
DeviceInformationItem itemWithPK = GetDeviceWithPartitionKey(itemid, partitionKey);
|
||||
|
||||
// Insert a new item
|
||||
ItemResponse<DeviceInformationItem> createResponse = await container.CreateItemAsync<DeviceInformationItem>(
|
||||
partitionKey: new PartitionKey(partitionKey),
|
||||
item: itemWithPK);
|
||||
Console.WriteLine("Creating Item {0} with Partition Key Status Code {1}", itemid, createResponse.StatusCode);
|
||||
|
||||
// Read the item back
|
||||
ItemResponse<DeviceInformationItem> readResponse = await container.ReadItemAsync<DeviceInformationItem>(
|
||||
partitionKey: new PartitionKey(partitionKey),
|
||||
id: itemid);
|
||||
Console.WriteLine("Reading Item {0} with Partition Key Status Code {1}", itemid, readResponse.StatusCode);
|
||||
|
||||
// Replace the content of the item
|
||||
itemWithPK.DeviceId = Guid.NewGuid().ToString();
|
||||
ItemResponse<DeviceInformationItem> replaceResponse = await container.ReplaceItemAsync<DeviceInformationItem>(
|
||||
partitionKey: new PartitionKey(partitionKey),
|
||||
id: itemWithPK.Id,
|
||||
item: itemWithPK);
|
||||
Console.WriteLine("Replacing Item {0} with Partition Key Status Code {1}", itemid, replaceResponse.StatusCode);
|
||||
|
||||
// Delete the item.
|
||||
ItemResponse<DeviceInformationItem> deleteResponse = await container.DeleteItemAsync<DeviceInformationItem>(
|
||||
partitionKey: new PartitionKey(partitionKey),
|
||||
id: itemid);
|
||||
Console.WriteLine("Deleting Item {0} with Partition Key Status Code {1}", itemid, deleteResponse.StatusCode);
|
||||
}
|
||||
// </ItemOperationsWithValidPartitionKeyValue>
|
||||
|
||||
/// <summary>
|
||||
/// The function demonstrates migrating documents that were inserted without a value for partition key, and those inserted
|
||||
/// pre-migration to other logical partitions, those with a value for partition key.
|
||||
/// </summary>
|
||||
// <MigratedItemsFromNonePartitionKeyToValidPartitionKeyValue>
|
||||
private static async Task MigratedItemsFromNonePartitionKeyToValidPartitionKeyValue(Container container)
|
||||
{
|
||||
// Pre-create a few items in the container to demo the migration
|
||||
const int ItemsToCreate = 4;
|
||||
// Insert a few items with no Partition Key
|
||||
for (int i = 0; i < ItemsToCreate; i++)
|
||||
{
|
||||
string itemid = Guid.NewGuid().ToString();
|
||||
DeviceInformationItem itemWithoutPK = GetDeviceWithNoPartitionKey(itemid);
|
||||
ItemResponse<DeviceInformationItem> createResponse = await container.CreateItemAsync<DeviceInformationItem>(
|
||||
partitionKey: PartitionKey.None,
|
||||
item: itemWithoutPK);
|
||||
}
|
||||
|
||||
// Query items on the container that have no partition key value by supplying NonePartitionKeyValue
|
||||
// The operation is made in batches to not lose work in case of partial execution
|
||||
int resultsFetched = 0;
|
||||
QueryDefinition sql = new QueryDefinition("select * from r");
|
||||
FeedIterator<DeviceInformationItem> setIterator = container.GetItemQueryIterator<DeviceInformationItem>(sql, requestOptions: new QueryRequestOptions() { PartitionKey = PartitionKey.None, MaxItemCount = 2 });
|
||||
while (setIterator.HasMoreResults)
|
||||
{
|
||||
FeedResponse<DeviceInformationItem> queryResponse = await setIterator.ReadNextAsync();
|
||||
resultsFetched += queryResponse.Count();
|
||||
|
||||
// For the items returned with NonePartitionKeyValue
|
||||
IEnumerator<DeviceInformationItem> iter = queryResponse.GetEnumerator();
|
||||
while (iter.MoveNext())
|
||||
{
|
||||
DeviceInformationItem item = iter.Current;
|
||||
if (item.DeviceId != null)
|
||||
{
|
||||
// Using existing deviceID for partition key
|
||||
item.PartitionKey = item.DeviceId;
|
||||
Console.WriteLine("Migrating item {0} to Partition {1}", item.Id, item.DeviceId);
|
||||
// Re-Insert into container with a partition key
|
||||
// This could result in exception if the same item was inserted in a previous run of the program on existing container
|
||||
// and the program stopped before the delete.
|
||||
ItemResponse<DeviceInformationItem> createResponseWithPk = await container.CreateItemAsync<DeviceInformationItem>(
|
||||
partitionKey: new PartitionKey(item.PartitionKey),
|
||||
item: item);
|
||||
|
||||
// Deleting item from fixed container with CosmosContainerSettings.NonePartitionKeyValue.
|
||||
ItemResponse<DeviceInformationItem> deleteResponseWithoutPk = await container.DeleteItemAsync<DeviceInformationItem>(
|
||||
partitionKey: PartitionKey.None,
|
||||
id: item.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// </MigratedItemsFromNonePartitionKeyToValidPartitionKeyValue>
|
||||
|
||||
private static DeviceInformationItem GetDeviceWithPartitionKey(string itemId, string partitionKey)
|
||||
{
|
||||
return new DeviceInformationItem
|
||||
{
|
||||
Id = itemId,
|
||||
DeviceId = Guid.NewGuid().ToString(),
|
||||
PartitionKey = partitionKey
|
||||
};
|
||||
}
|
||||
|
||||
private static DeviceInformationItem GetDeviceWithNoPartitionKey(string itemId)
|
||||
{
|
||||
return new DeviceInformationItem
|
||||
{
|
||||
Id = itemId,
|
||||
DeviceId = Guid.NewGuid().ToString(),
|
||||
};
|
||||
}
|
||||
|
||||
private static async Task CreateNonPartitionedContainerAsync(string endpoint, string authKey)
|
||||
{
|
||||
// Creating non partition Container, REST api used instead of .NET SDK as creation without a partition key is not supported anymore.
|
||||
Console.WriteLine("Creating container without a partition key");
|
||||
HttpClient client = new System.Net.Http.HttpClient();
|
||||
Uri baseUri = new Uri(endpoint);
|
||||
string verb = "POST";
|
||||
string resourceType = "colls";
|
||||
string resourceId = string.Format("dbs/{0}", Program.databaseId);
|
||||
string resourceLink = string.Format("dbs/{0}/colls", Program.databaseId);
|
||||
client.DefaultRequestHeaders.Add("x-ms-date", Program.utc_date);
|
||||
client.DefaultRequestHeaders.Add("x-ms-version", Program.PreNonPartitionedMigrationApiVersion);
|
||||
|
||||
string authHeader = GenerateMasterKeyAuthorizationSignature(verb, resourceId, resourceType, authKey, "master", "1.0");
|
||||
|
||||
client.DefaultRequestHeaders.Add("authorization", authHeader);
|
||||
string containerDefinition = "{\n \"id\": \"" + Program.containerId + "\"\n}";
|
||||
StringContent containerContent = new StringContent(containerDefinition);
|
||||
Uri requestUri = new Uri(baseUri, resourceLink);
|
||||
var response = await client.PostAsync(requestUri.ToString(), containerContent);
|
||||
Console.WriteLine("Create container response {0}", response.StatusCode);
|
||||
}
|
||||
|
||||
private static string GenerateMasterKeyAuthorizationSignature(string verb, string resourceId, string resourceType, string key, string keyType, string tokenVersion)
|
||||
{
|
||||
System.Security.Cryptography.HMACSHA256 hmacSha256 = new System.Security.Cryptography.HMACSHA256 { Key = Convert.FromBase64String(key) };
|
||||
|
||||
string payLoad = string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}\n{1}\n{2}\n{3}\n{4}\n",
|
||||
verb.ToLowerInvariant(),
|
||||
resourceType.ToLowerInvariant(),
|
||||
resourceId,
|
||||
utc_date.ToLowerInvariant(),
|
||||
""
|
||||
);
|
||||
|
||||
byte[] hashPayLoad = hmacSha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(payLoad));
|
||||
string signature = Convert.ToBase64String(hashPayLoad);
|
||||
|
||||
return System.Web.HttpUtility.UrlEncode(string.Format(System.Globalization.CultureInfo.InvariantCulture, "type={0}&ver={1}&sig={2}",
|
||||
keyType,
|
||||
tokenVersion,
|
||||
signature));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="NuGet" value="https://api.nuget.org/v3/index.json" />
|
||||
</packageSources>
|
||||
</configuration>
|
|
@ -1,424 +0,0 @@
|
|||
namespace Cosmos.Samples.Shared
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Azure.Cosmos;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
/// <summary>
|
||||
/// This class shows the different ways to execute item feed and queries.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// For help with SQL query syntax see:
|
||||
/// https://docs.microsoft.com/en-us/azure/cosmos-db/query-cheat-sheet
|
||||
/// https://docs.microsoft.com/en-us/azure/cosmos-db/how-to-sql-query
|
||||
/// </remarks>
|
||||
internal class Program
|
||||
{
|
||||
//Read configuration
|
||||
private static readonly string CosmosDatabaseId = "samples";
|
||||
private static readonly string containerId = "query-samples";
|
||||
|
||||
private static Database cosmosDatabase = null;
|
||||
|
||||
// Async main requires c# 7.1 which is set in the csproj with the LangVersion attribute
|
||||
// <Main>
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
IConfigurationRoot configuration = new ConfigurationBuilder()
|
||||
.AddJsonFile("appSettings.json")
|
||||
.Build();
|
||||
|
||||
string endpoint = configuration["EndPointUrl"];
|
||||
if (string.IsNullOrEmpty(endpoint))
|
||||
{
|
||||
throw new ArgumentNullException("Please specify a valid endpoint in the appSettings.json");
|
||||
}
|
||||
|
||||
string authKey = configuration["AuthorizationKey"];
|
||||
if (string.IsNullOrEmpty(authKey) || string.Equals(authKey, "Super secret key"))
|
||||
{
|
||||
throw new ArgumentException("Please specify a valid AuthorizationKey in the appSettings.json");
|
||||
}
|
||||
|
||||
//Read the Cosmos endpointUrl and authorizationKey from configuration
|
||||
//These values are available from the Azure Management Portal on the Cosmos Account Blade under "Keys"
|
||||
//NB > Keep these values in a safe & secure location. Together they provide Administrative access to your Cosmos account
|
||||
using (CosmosClient client = new CosmosClient(endpoint, authKey))
|
||||
{
|
||||
await Program.RunDemoAsync(client);
|
||||
}
|
||||
}
|
||||
catch (CosmosException cre)
|
||||
{
|
||||
Console.WriteLine(cre.ToString());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Exception baseException = e.GetBaseException();
|
||||
Console.WriteLine("Error: {0}, Message: {1}", e.Message, baseException.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.WriteLine("End of demo, press any key to exit.");
|
||||
Console.ReadKey();
|
||||
}
|
||||
}
|
||||
// </Main>
|
||||
|
||||
// <RunDemoAsync>
|
||||
private static async Task RunDemoAsync(CosmosClient client)
|
||||
{
|
||||
cosmosDatabase = await client.CreateDatabaseIfNotExistsAsync(CosmosDatabaseId);
|
||||
Container container = await Program.GetOrCreateContainerAsync(cosmosDatabase, containerId);
|
||||
|
||||
await Program.CreateItems(container);
|
||||
|
||||
await Program.ItemFeed(container);
|
||||
|
||||
await Program.ItemStreamFeed(container);
|
||||
|
||||
await Program.QueryItemsInPartitionAsStreams(container);
|
||||
|
||||
await Program.QueryPartitionedContainerInParallelAsync(container);
|
||||
|
||||
await Program.QueryWithSqlParameters(container);
|
||||
|
||||
// Uncomment to Cleanup
|
||||
//await cosmosDatabase.DeleteAsync();
|
||||
}
|
||||
// </RunDemoAsync>
|
||||
|
||||
// <ItemFeed>
|
||||
private static async Task ItemFeed(Container container)
|
||||
{
|
||||
List<Family> families = new List<Family>();
|
||||
|
||||
// SQL
|
||||
FeedIterator<Family> setIterator = container.GetItemQueryIterator<Family>(requestOptions: new QueryRequestOptions { MaxItemCount = 1});
|
||||
while (setIterator.HasMoreResults)
|
||||
{
|
||||
int count = 0;
|
||||
foreach (Family item in await setIterator.ReadNextAsync())
|
||||
{
|
||||
count++;
|
||||
Assert("Should only return 1 result at a time.", count <= 1);
|
||||
families.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
Assert("Expected two families", families.ToList().Count == 2);
|
||||
}
|
||||
// </ItemFeed>
|
||||
|
||||
// <ItemStreamFeed>
|
||||
private static async Task ItemStreamFeed(Container container)
|
||||
{
|
||||
int totalCount = 0;
|
||||
|
||||
// SQL
|
||||
FeedIterator setIterator = container.GetItemQueryStreamIterator();
|
||||
while (setIterator.HasMoreResults)
|
||||
{
|
||||
int count = 0;
|
||||
using (ResponseMessage response = await setIterator.ReadNextAsync())
|
||||
{
|
||||
response.EnsureSuccessStatusCode();
|
||||
count++;
|
||||
using (StreamReader sr = new StreamReader(response.Content))
|
||||
using (JsonTextReader jtr = new JsonTextReader(sr))
|
||||
{
|
||||
JsonSerializer jsonSerializer = new JsonSerializer();
|
||||
dynamic array = jsonSerializer.Deserialize<dynamic>(jtr);
|
||||
totalCount += array.Documents.Count;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Assert("Expected two families", totalCount == 2);
|
||||
}
|
||||
// </ItemStreamFeed>
|
||||
|
||||
// <QueryItemsInPartitionAsStreams>
|
||||
private static async Task QueryItemsInPartitionAsStreams(Container container)
|
||||
{
|
||||
// SQL
|
||||
FeedIterator setIterator = container.GetItemQueryStreamIterator(
|
||||
"SELECT F.id, F.LastName, F.IsRegistered FROM Families F",
|
||||
requestOptions: new QueryRequestOptions() {
|
||||
PartitionKey = new PartitionKey("Anderson"),
|
||||
MaxConcurrency = 1,
|
||||
MaxItemCount = 1
|
||||
});
|
||||
|
||||
int count = 0;
|
||||
while (setIterator.HasMoreResults)
|
||||
{
|
||||
using (ResponseMessage response = await setIterator.ReadNextAsync())
|
||||
{
|
||||
Assert("Response failed", response.IsSuccessStatusCode);
|
||||
count++;
|
||||
using (StreamReader sr = new StreamReader(response.Content))
|
||||
using (JsonTextReader jtr = new JsonTextReader(sr))
|
||||
{
|
||||
JsonSerializer jsonSerializer = new JsonSerializer();
|
||||
dynamic items = jsonSerializer.Deserialize<dynamic>(jtr).Documents;
|
||||
Assert("Expected one family", items.Count == 1);
|
||||
dynamic item = items[0];
|
||||
Assert($"Expected LastName: Anderson Actual: {item.LastName}", string.Equals("Anderson", item.LastName.ToString(), StringComparison.InvariantCulture));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Assert("Expected 1 family", count == 1);
|
||||
}
|
||||
// </QueryItemsInPartitionAsStreams>
|
||||
|
||||
// <QueryWithSqlParameters>
|
||||
private static async Task QueryWithSqlParameters(Container container)
|
||||
{
|
||||
// Query using two properties within each item. WHERE Id == "" AND Address.City == ""
|
||||
// notice here how we are doing an equality comparison on the string value of City
|
||||
|
||||
QueryDefinition query = new QueryDefinition("SELECT * FROM Families f WHERE f.id = @id AND f.Address.City = @city")
|
||||
.WithParameter("@id", "AndersonFamily")
|
||||
.WithParameter("@city", "Seattle");
|
||||
|
||||
List<Family> results = new List<Family>();
|
||||
FeedIterator<Family> resultSetIterator = container.GetItemQueryIterator<Family>(query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Anderson")});
|
||||
while (resultSetIterator.HasMoreResults)
|
||||
{
|
||||
results.AddRange((await resultSetIterator.ReadNextAsync()));
|
||||
}
|
||||
|
||||
Assert("Expected only 1 family", results.Count == 1);
|
||||
}
|
||||
// </QueryWithSqlParameters>
|
||||
|
||||
// <QueryPartitionedContainerInParallelAsync>
|
||||
private static async Task QueryPartitionedContainerInParallelAsync(Container container)
|
||||
{
|
||||
List<Family> familiesSerial = new List<Family>();
|
||||
string queryText = "SELECT * FROM Families";
|
||||
|
||||
// 0 maximum parallel tasks, effectively serial execution
|
||||
QueryRequestOptions options = new QueryRequestOptions() { MaxBufferedItemCount = 100 };
|
||||
options.MaxConcurrency = 0;
|
||||
FeedIterator<Family> query = container.GetItemQueryIterator<Family>(
|
||||
queryText,
|
||||
requestOptions: options);
|
||||
while (query.HasMoreResults)
|
||||
{
|
||||
foreach (Family family in await query.ReadNextAsync())
|
||||
{
|
||||
familiesSerial.Add(family);
|
||||
}
|
||||
}
|
||||
|
||||
Assert("Parallel Query expected two families", familiesSerial.ToList().Count == 2);
|
||||
|
||||
// 1 maximum parallel tasks, 1 dedicated asynchronous task to continuously make REST calls
|
||||
List<Family> familiesParallel1 = new List<Family>();
|
||||
|
||||
options.MaxConcurrency = 1;
|
||||
query = container.GetItemQueryIterator<Family>(
|
||||
queryText,
|
||||
requestOptions: options);
|
||||
|
||||
while (query.HasMoreResults)
|
||||
{
|
||||
foreach (Family family in await query.ReadNextAsync())
|
||||
{
|
||||
familiesParallel1.Add(family);
|
||||
}
|
||||
}
|
||||
|
||||
Assert("Parallel Query expected two families", familiesParallel1.ToList().Count == 2);
|
||||
AssertSequenceEqual("Parallel query returns result out of order compared to serial execution", familiesSerial, familiesParallel1);
|
||||
|
||||
|
||||
// 10 maximum parallel tasks, a maximum of 10 dedicated asynchronous tasks to continuously make REST calls
|
||||
List<Family> familiesParallel10 = new List<Family>();
|
||||
|
||||
options.MaxConcurrency = 10;
|
||||
query = container.GetItemQueryIterator<Family>(
|
||||
queryText,
|
||||
requestOptions: options);
|
||||
|
||||
while (query.HasMoreResults)
|
||||
{
|
||||
foreach (Family family in await query.ReadNextAsync())
|
||||
{
|
||||
familiesParallel10.Add(family);
|
||||
}
|
||||
}
|
||||
|
||||
Assert("Parallel Query expected two families", familiesParallel10.ToList().Count == 2);
|
||||
AssertSequenceEqual("Parallel query returns result out of order compared to serial execution", familiesSerial, familiesParallel10);
|
||||
}
|
||||
// </QueryPartitionedContainerInParallelAsync>
|
||||
|
||||
/// <summary>
|
||||
/// Creates the items used in this Sample
|
||||
/// </summary>
|
||||
/// <param name="container">The selfLink property for the CosmosContainer where items will be created.</param>
|
||||
/// <returns>None</returns>
|
||||
// <CreateItems>
|
||||
private static async Task CreateItems(Container container)
|
||||
{
|
||||
Family AndersonFamily = new Family
|
||||
{
|
||||
Id = "AndersonFamily",
|
||||
LastName = "Anderson",
|
||||
Parents = new Parent[]
|
||||
{
|
||||
new Parent { FirstName = "Thomas" },
|
||||
new Parent { FirstName = "Mary Kay"}
|
||||
},
|
||||
Children = new Child[]
|
||||
{
|
||||
new Child
|
||||
{
|
||||
FirstName = "Henriette Thaulow",
|
||||
Gender = "female",
|
||||
Grade = 5,
|
||||
Pets = new []
|
||||
{
|
||||
new Pet { GivenName = "Fluffy" }
|
||||
}
|
||||
}
|
||||
},
|
||||
Address = new Address { State = "WA", County = "King", City = "Seattle" },
|
||||
IsRegistered = true,
|
||||
RegistrationDate = DateTime.UtcNow.AddDays(-1)
|
||||
};
|
||||
|
||||
await container.UpsertItemAsync<Family>(AndersonFamily, new PartitionKey(AndersonFamily.PartitionKey));
|
||||
|
||||
Family WakefieldFamily = new Family
|
||||
{
|
||||
Id = "WakefieldFamily",
|
||||
LastName = "Wakefield",
|
||||
Parents = new[] {
|
||||
new Parent { FamilyName= "Wakefield", FirstName= "Robin" },
|
||||
new Parent { FamilyName= "Miller", FirstName= "Ben" }
|
||||
},
|
||||
Children = new Child[] {
|
||||
new Child
|
||||
{
|
||||
FamilyName= "Merriam",
|
||||
FirstName= "Jesse",
|
||||
Gender= "female",
|
||||
Grade= 8,
|
||||
Pets= new Pet[] {
|
||||
new Pet { GivenName= "Goofy" },
|
||||
new Pet { GivenName= "Shadow" }
|
||||
}
|
||||
},
|
||||
new Child
|
||||
{
|
||||
FirstName= "Lisa",
|
||||
Gender= "female",
|
||||
Grade= 1
|
||||
}
|
||||
},
|
||||
Address = new Address { State = "NY", County = "Manhattan", City = "NY" },
|
||||
IsRegistered = false,
|
||||
RegistrationDate = DateTime.UtcNow.AddDays(-30)
|
||||
};
|
||||
|
||||
await container.UpsertItemAsync<Family>(WakefieldFamily, new PartitionKey(WakefieldFamily.PartitionKey));
|
||||
}
|
||||
// </CreateItems>
|
||||
|
||||
/// <summary>
|
||||
/// Get a DocuemntContainer by id, or create a new one if one with the id provided doesn't exist.
|
||||
/// </summary>
|
||||
/// <param name="id">The id of the CosmosContainer to search for, or create.</param>
|
||||
/// <returns>The matched, or created, CosmosContainer object</returns>
|
||||
// <GetOrCreateContainerAsync>
|
||||
private static async Task<Container> GetOrCreateContainerAsync(Database database, string containerId)
|
||||
{
|
||||
ContainerProperties containerProperties = new ContainerProperties(id: containerId, partitionKeyPath: "/LastName");
|
||||
|
||||
return await database.CreateContainerIfNotExistsAsync(
|
||||
containerProperties: containerProperties,
|
||||
throughput: 400);
|
||||
}
|
||||
// </GetOrCreateContainerAsync>
|
||||
|
||||
private static void Assert(string message, bool condition)
|
||||
{
|
||||
if (!condition)
|
||||
{
|
||||
throw new ApplicationException(message);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AssertSequenceEqual(string message, List<Family> list1, List<Family> list2)
|
||||
{
|
||||
if (!string.Join(",", list1.Select(family => family.Id).ToArray()).Equals(
|
||||
string.Join(",", list1.Select(family => family.Id).ToArray())))
|
||||
{
|
||||
throw new ApplicationException(message);
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class Parent
|
||||
{
|
||||
public string FamilyName { get; set; }
|
||||
public string FirstName { get; set; }
|
||||
}
|
||||
|
||||
internal sealed class Child
|
||||
{
|
||||
public string FamilyName { get; set; }
|
||||
public string FirstName { get; set; }
|
||||
public string Gender { get; set; }
|
||||
public int Grade { get; set; }
|
||||
public Pet[] Pets { get; set; }
|
||||
}
|
||||
|
||||
internal sealed class Pet
|
||||
{
|
||||
public string GivenName { get; set; }
|
||||
}
|
||||
|
||||
internal sealed class Address
|
||||
{
|
||||
public string State { get; set; }
|
||||
public string County { get; set; }
|
||||
public string City { get; set; }
|
||||
}
|
||||
|
||||
internal sealed class Family
|
||||
{
|
||||
[JsonProperty(PropertyName = "id")]
|
||||
public string Id { get; set; }
|
||||
|
||||
public string LastName { get; set; }
|
||||
|
||||
public Parent[] Parents { get; set; }
|
||||
|
||||
public Child[] Children { get; set; }
|
||||
|
||||
public Address Address { get; set; }
|
||||
|
||||
public bool IsRegistered { get; set; }
|
||||
|
||||
public DateTime RegistrationDate { get; set; }
|
||||
|
||||
public string PartitionKey => this.LastName;
|
||||
|
||||
public static string PartitionKeyPath => "/LastName";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Shared\Shared.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\AppSettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "a79c0efd3640458e890cffe2d13ed253",
|
||||
"FamilyId": 3931,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "7affe11d771e4865ba56100d1c1b3a6c",
|
||||
"FamilyId": 7073,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "e633f3f681704672b8cf15b03acf71bd",
|
||||
"FamilyId": 4730,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "17cc67a07d3d45f3ab5be91da5d0dca1",
|
||||
"FamilyId": 2450,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "56a8e5abe6634a80a37407515f406f55",
|
||||
"FamilyId": 1756,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "d77c6add612049fe89d2a84e032acb06",
|
||||
"FamilyId": 9429,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "46667adfd7bf429fb817383e2b78d680",
|
||||
"FamilyId": 334,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "d93af7d3706e4f28882920366c017cd7",
|
||||
"FamilyId": 989,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "5c87b20b492b4807b3bcce5690ae3be2",
|
||||
"FamilyId": 5426,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "94e454fc39a04d0b82202212fb9f1609",
|
||||
"FamilyId": 4144,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "e9226d688d354712aedaa95d4bc8d7f4",
|
||||
"FamilyId": 4637,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "f8d178d13b904ad5938e59e7550abddc",
|
||||
"FamilyId": 256,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "8c3a0493f7184951bb8305eb59bc8351",
|
||||
"FamilyId": 1040,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "4d66aeaf7884493aa23b3e132443b3bf",
|
||||
"FamilyId": 2317,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "08a58bfa0f7e4d358a59b38fa5375fc1",
|
||||
"FamilyId": 8534,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "19ff340e73c24da2bcbba768a42aadc2",
|
||||
"FamilyId": 4724,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "c64229fc66eb4ce99c14e1ae7dcb1f5f",
|
||||
"FamilyId": 4541,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "291e7e87091f40b58380d5ebfc5523d1",
|
||||
"FamilyId": 3178,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "fc06c2477f2d4f069bc56e625de3b32d",
|
||||
"FamilyId": 8713,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "b47d9efa6fc04fdba42dd72c45b86659",
|
||||
"FamilyId": 9899,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "7d3d9a0de0164da982ca31fc17efef1b",
|
||||
"FamilyId": 5378,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "f2cc40ddbf124a578cda637a5ebe1310",
|
||||
"FamilyId": 1545,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "31cd0dfb04bb49cc95840251c2ac2bd0",
|
||||
"FamilyId": 8046,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "5f74efef38e8462da2c9e4fb538196bc",
|
||||
"FamilyId": 3963,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "a26e994668154b4e95615cba9578a150",
|
||||
"FamilyId": 7991,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "81dfaa5e296a49ac9daa3e2c6a9a7a30",
|
||||
"FamilyId": 4687,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "7f157adf4ba64c70a897c78f7fd5e077",
|
||||
"FamilyId": 5546,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "54e71ec8d79c4497aa5d7d2c99f23588",
|
||||
"FamilyId": 2293,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "c96c6dfbd35343978b4419ca8f657988",
|
||||
"FamilyId": 3936,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "e1ee83e3a20941a99a1e1b84807d9833",
|
||||
"FamilyId": 5468,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "641d637e20da4fc99aa23978746bf57c",
|
||||
"FamilyId": 1187,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "645fe1cf6b7e4a3482f27d619219aba5",
|
||||
"FamilyId": 9379,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "b25ca65596ac45b4b18961c78d82a32e",
|
||||
"FamilyId": 7810,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "0d7db32c6e21404fa7a8c0ff0872ae11",
|
||||
"FamilyId": 9875,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "b4c6495a5f4a4a948e89252461521933",
|
||||
"FamilyId": 6357,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "a519000d1ec04389bc51f674b1cff9d0",
|
||||
"FamilyId": 5420,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "86d37b74ed7d45e8b081257cf632f675",
|
||||
"FamilyId": 1731,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "48ff8a643b2b4a3d827438a0128495a6",
|
||||
"FamilyId": 3406,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "ba54bf7e37dc400ca2edc6a9632de8fb",
|
||||
"FamilyId": 763,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "a7f9a9cedee9443589d4bcc84a061449",
|
||||
"FamilyId": 8267,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "d30e771f81d64b3a86c9e32fd0ba1c3a",
|
||||
"FamilyId": 6134,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "ad6bbd21f9c54d7d9b2591ebb57e3d1e",
|
||||
"FamilyId": 1819,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "e6f17b3046fc4c9aa10d5f33e45ed82f",
|
||||
"FamilyId": 8379,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "342f1abb9d8142789c2cc0761ff2dd4f",
|
||||
"FamilyId": 620,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "dc1c429014d646adac5a81ae2c2f1914",
|
||||
"FamilyId": 3605,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "fe05fabb55c8402680c4cfd48421888e",
|
||||
"FamilyId": 3049,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "f7ec238ffeb3493b8026976d21631c07",
|
||||
"FamilyId": 5573,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "97daaf1fce9d41428266e69f2c9d1698",
|
||||
"FamilyId": 7581,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "38b96202158f404fa6e28e10b376fed5",
|
||||
"FamilyId": 7078,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "05c3cb8c92dc477c8185ee7e84c07cf6",
|
||||
"FamilyId": 3543,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "ab6c105a5d1645bb97a42d5cf4d9dc6a",
|
||||
"FamilyId": 8293,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "86a494efbd3647a7ae6321943149e71d",
|
||||
"FamilyId": 5397,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "181880cdac034d79be934d6b4a4ecbca",
|
||||
"FamilyId": 2348,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "b7181cc65030491d8ecfca5c0828533b",
|
||||
"FamilyId": 6498,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "05adb6c704eb4f7986482749c2da0770",
|
||||
"FamilyId": 784,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "884e722875b34a7eb2b1012bb5f550ed",
|
||||
"FamilyId": 7643,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "e9ed3151fe6a41f888d289a7f1cf4a73",
|
||||
"FamilyId": 5036,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "db6f4a57a7d64aa0ba7ba8a306b02aa7",
|
||||
"FamilyId": 3150,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "2d9eb45f62e642b793e6b34c088a6c72",
|
||||
"FamilyId": 9658,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "1ce67274060c451098eb48d58c1435da",
|
||||
"FamilyId": 4585,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "4338b4f0b483468aaefdaf2d344a73c4",
|
||||
"FamilyId": 7598,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "93f938cd0a864179860c51a6698a826d",
|
||||
"FamilyId": 5622,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "e376119f72ab42aca5ceb8edf5f8afd4",
|
||||
"FamilyId": 43,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "8d14f77e456e43a1ac7ab07489d4d341",
|
||||
"FamilyId": 6903,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "52d0579510c641fab55ef54d9dde0ad2",
|
||||
"FamilyId": 9463,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "acf4cddd93724a6c8d5b71eb0843436b",
|
||||
"FamilyId": 5492,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "ed54b31afaf6472b8342928b477c9d6e",
|
||||
"FamilyId": 4865,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "df6ffc9bf2c94771b2b85d8fe98e0629",
|
||||
"FamilyId": 6131,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "839edeb6854d447e97cfb3b8c5b5fb2d",
|
||||
"FamilyId": 9801,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "2c4b7c96fa6f453fad6532d408678f46",
|
||||
"FamilyId": 6046,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "a2fd3ac8aaca4d6fb54ec085e41eb123",
|
||||
"FamilyId": 6333,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "39b7148eca104723abc7a622537a8c5c",
|
||||
"FamilyId": 4762,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "3f0394114afa4b0aa7661fde577c4977",
|
||||
"FamilyId": 4836,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "b17ed790e42445409dc166727de8b33a",
|
||||
"FamilyId": 585,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "74fca8a411e24139b67619c2abfc5c91",
|
||||
"FamilyId": 5127,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"id": "55ae3081bef74511a867f04adfd081ec",
|
||||
"FamilyId": 3960,
|
||||
"LastName": "Andersen",
|
||||
"Parents": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Thomas"
|
||||
},
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Mary Kay"
|
||||
}
|
||||
],
|
||||
"Children": [
|
||||
{
|
||||
"FamilyName": null,
|
||||
"FirstName": "Henriette Thaulow",
|
||||
"Gender": "female",
|
||||
"Grade": 5,
|
||||
"Pets": [
|
||||
{
|
||||
"GivenName": "Fluffy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Address": {
|
||||
"State": "WA",
|
||||
"County": "King",
|
||||
"City": "Seattle"
|
||||
},
|
||||
"IsRegistered": false
|
||||
}
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче