Изменить сущность

This commit is contained in:
Roman Efremov 2024-12-25 14:54:25 +05:00
parent df7148688d
commit 50c535de5e
41 changed files with 56 additions and 385 deletions

View File

@ -9,7 +9,6 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.10" />
<PackageReference Include="NPlot" Version="0.9.10" />
<PackageReference Include="System.Drawing.Common" Version="9.0.0" />
<PackageReference Include="xunit.extensibility.core" Version="2.9.2" />
</ItemGroup>

View File

@ -1,11 +1,11 @@
using Microsoft.EntityFrameworkCore;
using Persistence.Benchmark.Database.Entities;
using DD.Persistence.Database;
using DD.Persistence.Database.Entity;
namespace Persistence.Benchmark.Database;
public class BenchmarkDbContext : PersistenceDbContext
{
public new DbSet<ParameterData> ParameterData => Set<ParameterData>();
public DbSet<ParameterData> ParameterData => Set<ParameterData>();
public BenchmarkDbContext(DbContextOptions options) : base(options)
{
}

View File

@ -1,8 +1,4 @@
using BenchmarkDotNet.Running;
using Persistence.Benchmark;
using Persistence.Benchmark.Tests;
using DD.Persistence.API;
using System.Runtime.InteropServices;
using Persistence.Benchmark.Tests;
public class Program
{

View File

@ -8,6 +8,7 @@ namespace Persistence.Benchmark.Tests;
public static class WitsDataBenchmark
{
private const string discriminatorId = "fef21bfd-e924-473d-b6c8-e4377e38245d";
private const int chunkSize = 25_000;
public static async Task ExecuteTest(int count)
{
@ -24,11 +25,6 @@ public static class WitsDataBenchmark
var data = GenerateData(count);
var sw = new Stopwatch();
var abscissaData = new List<double>() { };
var ordinateData = new List<double>() { };
var saved = 0;
foreach (var item in data)
{
@ -37,23 +33,20 @@ public static class WitsDataBenchmark
sw.Start();
var response = await client.AddRange(item, source.Token);
sw.Stop();
Console.WriteLine($"Сохранено: {response.ToString()}");
saved = saved + response;
abscissaData.Add(saved / 100_000);
Console.WriteLine($"Затрачено времени на сохранение части: {sw.Elapsed - time}");
ordinateData.Add((double)(sw.Elapsed - time).TotalSeconds);
Console.WriteLine($"Сохранено: {saved.ToString()}");
}
Console.WriteLine($"Затрачено времени на сохранение: {sw.Elapsed}");
var dis = Guid.Parse(discriminatorId);
var discriminator = Guid.Parse(discriminatorId);
var date = DateTime.Now.AddDays(-1);
Console.WriteLine($"\nВычитка...");
sw = new Stopwatch();
sw.Start();
var get = await client.GetPart(dis, date, count, source.Token);
var get = await client.GetPart(discriminator, date, count, source.Token);
sw.Stop();
Console.WriteLine($"Затрачено времени на вычитку: {sw.Elapsed}");
@ -68,16 +61,18 @@ public static class WitsDataBenchmark
{
var result = new List<List<WitsDataDto>>();
int enumerableCount = countToCreate / 25_000 + (countToCreate % 25_000 == 0 ? 0 : 1);
int enumerableCount = countToCreate / chunkSize + (countToCreate % chunkSize == 0 ? 0 : 1);
for (var k = 0; k < enumerableCount; k++)
{
var dtos = new List<WitsDataDto>();
for (var j = 0; j < 1000; j++)
{
for (var i = 0; i < 25; i++)
for (var i = 0; i < chunkSize / 1000; i++)
{
var timestamped = DateTimeOffset.UtcNow;
var random = new Random();
var timestamped = DateTimeOffset.UtcNow.AddSeconds(random.Next(1, 60 * 60 * 24) * -1);
dtos.Add(new WitsDataDto()
{
DiscriminatorId = Guid.Parse(discriminatorId),

View File

@ -1,61 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace DD.Persistence.Database.Postgres.Migrations.PersistencePostgres
{
/// <inheritdoc />
public partial class ParameterDataMigration : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "ParameterData",
columns: table => new
{
DiscriminatorId = table.Column<Guid>(type: "uuid", nullable: false, comment: "Дискриминатор системы"),
ParameterId = table.Column<int>(type: "integer", nullable: false, comment: "Id параметра")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Timestamp = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, comment: "Временная отметка"),
Value = table.Column<string>(type: "varchar(256)", nullable: true, comment: "Значение параметра в виде строки")
},
constraints: table =>
{
table.PrimaryKey("PK_ParameterData", x => new { x.DiscriminatorId, x.ParameterId, x.Timestamp });
});
string sql;
for (int i = 1; i <= 25; i++)
{
sql = $"create table if not exists \"ParameterData{i}\" (like public.\"ParameterData\" including all) inherits (public.\"ParameterData\");";
migrationBuilder.Sql(sql);
}
//sql = "create or replace function partition_for_parameter_data() returns trigger as $$ " +
// "DECLARE " +
// " v_parition_name text; " +
// "BEGIN " +
// " v_parition_name := format( 'ParameterData%s', NEW.\"ParameterId\" / 1000 ); " +
// " execute 'INSERT INTO public.\"' || v_parition_name || '\" VALUES ( ($1).* )' USING NEW; " +
// " return NULL; " +
// "END; " +
// "$$ language plpgsql;";
//migrationBuilder.Sql(sql);
//sql = "create or replace trigger partition_parameter_data " +
// "before insert on public.\"ParameterData\" " +
// "for each row execute procedure public.partition_for_parameter_data();";
//migrationBuilder.Sql(sql);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "ParameterData");
}
}
}

View File

@ -12,7 +12,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace DD.Persistence.Database.Postgres.Migrations
{
[DbContext(typeof(PersistencePostgresContext))]
[Migration("20241220062251_Init")]
[Migration("20241225094516_Init")]
partial class Init
{
/// <inheritdoc />
@ -20,7 +20,7 @@ namespace DD.Persistence.Database.Postgres.Migrations
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.10")
.HasAnnotation("ProductVersion", "9.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
@ -46,6 +46,30 @@ namespace DD.Persistence.Database.Postgres.Migrations
b.ToTable("DataSourceSystem");
});
modelBuilder.Entity("DD.Persistence.Database.Entity.ParameterData", b =>
{
b.Property<Guid>("DiscriminatorId")
.HasColumnType("uuid")
.HasComment("Дискриминатор системы");
b.Property<int>("ParameterId")
.HasColumnType("integer")
.HasComment("Id параметра");
b.Property<DateTimeOffset>("Timestamp")
.HasColumnType("timestamp with time zone")
.HasComment("Временная отметка");
b.Property<object>("Value")
.IsRequired()
.HasColumnType("jsonb")
.HasComment("Значение параметра");
b.HasKey("DiscriminatorId", "ParameterId", "Timestamp");
b.ToTable("ParameterData");
});
modelBuilder.Entity("DD.Persistence.Database.Entity.TechMessage", b =>
{
b.Property<Guid>("EventId")

View File

@ -81,7 +81,7 @@ namespace DD.Persistence.Database.Postgres.Migrations
DiscriminatorId = table.Column<Guid>(type: "uuid", nullable: false, comment: "Дискриминатор системы"),
ParameterId = table.Column<int>(type: "integer", nullable: false, comment: "Id параметра"),
Timestamp = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, comment: "Временная отметка"),
Value = table.Column<string>(type: "varchar(256)", nullable: false, comment: "Значение параметра в виде строки")
Value = table.Column<object>(type: "jsonb", nullable: false, comment: "Значение параметра")
},
constraints: table =>
{

View File

@ -17,7 +17,7 @@ namespace DD.Persistence.Database.Postgres.Migrations
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.10")
.HasAnnotation("ProductVersion", "9.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
@ -46,32 +46,27 @@ namespace DD.Persistence.Database.Postgres.Migrations
modelBuilder.Entity("DD.Persistence.Database.Entity.ParameterData", b =>
{
b.Property<Guid>("DiscriminatorId")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasComment("Дискриминатор системы");
b.Property<int>("ParameterId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasComment("Id параметра");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("ParameterId"));
b.Property<DateTimeOffset>("Timestamp")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasComment("Временная отметка");
b.Property<string>("Value")
.HasColumnType("varchar(256)")
.HasComment("Значение параметра в виде строки");
b.Property<object>("Value")
.IsRequired()
.HasColumnType("jsonb")
.HasComment("Значение параметра");
b.HasKey("DiscriminatorId", "ParameterId", "Timestamp");
b.ToTable("ParameterData");
});
modelBuilder.Entity("DD.Persistence.Database.Entity.TechMessage", b =>
{
b.Property<Guid>("EventId")

View File

@ -2,7 +2,7 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DD.Persistence.Database.Entity.ParameterData;
namespace DD.Persistence.Database.Entity;
[Table("ParameterData")]
[PrimaryKey(nameof(DiscriminatorId), nameof(ParameterId), nameof(Timestamp))]
@ -14,8 +14,8 @@ public class ParameterData
[Comment("Id параметра")]
public int ParameterId { get; set; }
[Column(TypeName = "varchar(256)"), Comment("Значение параметра в виде строки")]
public string Value { get; set; }
[Column(TypeName = "jsonb"), Comment("Значение параметра")]
public required object Value { get; set; }
[Comment("Временная отметка")]
public DateTimeOffset Timestamp { get; set; }

View File

@ -1,10 +0,0 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DD.Persistence.Database.Entity.ParameterData;
[Table("ParameterData1")]
public class ParameterData1 : ParameterData
{
}

View File

@ -1,10 +0,0 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DD.Persistence.Database.Entity.ParameterData;
[Table("ParameterData10")]
public class ParameterData10 : ParameterData
{
}

View File

@ -1,10 +0,0 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DD.Persistence.Database.Entity.ParameterData;
[Table("ParameterData11")]
public class ParameterData11 : ParameterData
{
}

View File

@ -1,10 +0,0 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DD.Persistence.Database.Entity.ParameterData;
[Table("ParameterData12")]
public class ParameterData12 : ParameterData
{
}

View File

@ -1,10 +0,0 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DD.Persistence.Database.Entity.ParameterData;
[Table("ParameterData13")]
public class ParameterData13 : ParameterData
{
}

View File

@ -1,10 +0,0 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DD.Persistence.Database.Entity.ParameterData;
[Table("ParameterData14")]
public class ParameterData14 : ParameterData
{
}

View File

@ -1,10 +0,0 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DD.Persistence.Database.Entity.ParameterData;
[Table("ParameterData15")]
public class ParameterData15 : ParameterData
{
}

View File

@ -1,10 +0,0 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DD.Persistence.Database.Entity.ParameterData;
[Table("ParameterData16")]
public class ParameterData16 : ParameterData
{
}

View File

@ -1,10 +0,0 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DD.Persistence.Database.Entity.ParameterData;
[Table("ParameterData17")]
public class ParameterData17 : ParameterData
{
}

View File

@ -1,10 +0,0 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DD.Persistence.Database.Entity.ParameterData;
[Table("ParameterData18")]
public class ParameterData18 : ParameterData
{
}

View File

@ -1,10 +0,0 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DD.Persistence.Database.Entity.ParameterData;
[Table("ParameterData19")]
public class ParameterData19 : ParameterData
{
}

View File

@ -1,10 +0,0 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DD.Persistence.Database.Entity.ParameterData;
[Table("ParameterData2")]
public class ParameterData2 : ParameterData
{
}

View File

@ -1,10 +0,0 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DD.Persistence.Database.Entity.ParameterData;
[Table("ParameterData20")]
public class ParameterData20 : ParameterData
{
}

View File

@ -1,10 +0,0 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DD.Persistence.Database.Entity.ParameterData;
[Table("ParameterData21")]
public class ParameterData21 : ParameterData
{
}

View File

@ -1,10 +0,0 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DD.Persistence.Database.Entity.ParameterData;
[Table("ParameterData22")]
public class ParameterData22 : ParameterData
{
}

View File

@ -1,10 +0,0 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DD.Persistence.Database.Entity.ParameterData;
[Table("ParameterData23")]
public class ParameterData23 : ParameterData
{
}

View File

@ -1,10 +0,0 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DD.Persistence.Database.Entity.ParameterData;
[Table("ParameterData24")]
public class ParameterData24 : ParameterData
{
}

View File

@ -1,10 +0,0 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DD.Persistence.Database.Entity.ParameterData;
[Table("ParameterData25")]
public class ParameterData25 : ParameterData
{
}

View File

@ -1,10 +0,0 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DD.Persistence.Database.Entity.ParameterData;
[Table("ParameterData3")]
public class ParameterData3 : ParameterData
{
}

View File

@ -1,10 +0,0 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DD.Persistence.Database.Entity.ParameterData;
[Table("ParameterData4")]
public class ParameterData4 : ParameterData
{
}

View File

@ -1,10 +0,0 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DD.Persistence.Database.Entity.ParameterData;
[Table("ParameterData5")]
public class ParameterData5 : ParameterData
{
}

View File

@ -1,10 +0,0 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DD.Persistence.Database.Entity.ParameterData;
[Table("ParameterData6")]
public class ParameterData6 : ParameterData
{
}

View File

@ -1,10 +0,0 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DD.Persistence.Database.Entity.ParameterData;
[Table("ParameterData7")]
public class ParameterData7 : ParameterData
{
}

View File

@ -1,10 +0,0 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DD.Persistence.Database.Entity.ParameterData;
[Table("ParameterData8")]
public class ParameterData8 : ParameterData
{
}

View File

@ -1,10 +0,0 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DD.Persistence.Database.Entity.ParameterData;
[Table("ParameterData9")]
public class ParameterData9 : ParameterData
{
}

View File

@ -1,7 +1,6 @@
using Microsoft.EntityFrameworkCore;
using DD.Persistence.Database.Entity;
using DD.Persistence.Database.Model;
using DD.Persistence.Database.Entity.ParameterData;
namespace DD.Persistence.Database;
@ -21,32 +20,6 @@ public class PersistenceDbContext : DbContext
public DbSet<TechMessage> TechMessage => Set<TechMessage>();
public DbSet<ParameterData> ParameterData => Set<ParameterData>();
public DbSet<ParameterData1> ParameterData1 => Set<ParameterData1>();
public DbSet<ParameterData2> ParameterData2 => Set<ParameterData2>();
public DbSet<ParameterData3> ParameterData3 => Set<ParameterData3>();
public DbSet<ParameterData4> ParameterData4 => Set<ParameterData4>();
public DbSet<ParameterData5> ParameterData5 => Set<ParameterData5>();
public DbSet<ParameterData6> ParameterData6 => Set<ParameterData6>();
public DbSet<ParameterData7> ParameterData7 => Set<ParameterData7>();
public DbSet<ParameterData8> ParameterData8 => Set<ParameterData8>();
public DbSet<ParameterData9> ParameterData9 => Set<ParameterData9>();
public DbSet<ParameterData10> ParameterData10 => Set<ParameterData10>();
public DbSet<ParameterData11> ParameterData11 => Set<ParameterData11>();
public DbSet<ParameterData12> ParameterData12 => Set<ParameterData12>();
public DbSet<ParameterData13> ParameterData13 => Set<ParameterData13>();
public DbSet<ParameterData14> ParameterData14 => Set<ParameterData14>();
public DbSet<ParameterData15> ParameterData15 => Set<ParameterData15>();
public DbSet<ParameterData16> ParameterData16 => Set<ParameterData16>();
public DbSet<ParameterData17> ParameterData17 => Set<ParameterData17>();
public DbSet<ParameterData18> ParameterData18 => Set<ParameterData18>();
public DbSet<ParameterData19> ParameterData19 => Set<ParameterData19>();
public DbSet<ParameterData20> ParameterData20 => Set<ParameterData20>();
public DbSet<ParameterData21> ParameterData21 => Set<ParameterData21>();
public DbSet<ParameterData22> ParameterData22 => Set<ParameterData22>();
public DbSet<ParameterData23> ParameterData23 => Set<ParameterData23>();
public DbSet<ParameterData24> ParameterData24 => Set<ParameterData24>();
public DbSet<ParameterData25> ParameterData25 => Set<ParameterData25>();
public DbSet<DataSourceSystem> DataSourceSystem => Set<DataSourceSystem>();

View File

@ -4,7 +4,7 @@ using System.Net;
using Xunit;
using DD.Persistence.Client.Clients.Interfaces;
using DD.Persistence.Client;
using DD.Persistence.Database.Entity.ParameterData;
using DD.Persistence.Database.Entity;
namespace DD.Persistence.IntegrationTests.Controllers;
public class WitsDataControllerTest : BaseIntegrationTest

View File

@ -2,7 +2,7 @@
using Microsoft.EntityFrameworkCore;
using DD.Persistence.Models;
using DD.Persistence.Repositories;
using DD.Persistence.Database.Entity.ParameterData;
using DD.Persistence.Database.Entity;
namespace DD.Persistence.Repository.Repositories;
public class ParameterRepository : IParameterRepository

View File

@ -18,7 +18,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DD.Persistence.Client", "DD
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DD.Persistence.App", "DD.Persistence.App\DD.Persistence.App.csproj", "{063238BF-E982-43FA-9DDB-7D7D279086D8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Persistence.Benchmark", "Persistence.Benchmark\Persistence.Benchmark.csproj", "{27455F8C-6986-46F1-AD3E-B9D0C7AC85D1}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DD.Persistence.Benchmark", "DD.Persistence.Benchmark\DD.Persistence.Benchmark.csproj", "{89975A38-C78B-4464-A04D-D63E8745062D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -58,10 +58,10 @@ Global
{063238BF-E982-43FA-9DDB-7D7D279086D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{063238BF-E982-43FA-9DDB-7D7D279086D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{063238BF-E982-43FA-9DDB-7D7D279086D8}.Release|Any CPU.Build.0 = Release|Any CPU
{27455F8C-6986-46F1-AD3E-B9D0C7AC85D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{27455F8C-6986-46F1-AD3E-B9D0C7AC85D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{27455F8C-6986-46F1-AD3E-B9D0C7AC85D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{27455F8C-6986-46F1-AD3E-B9D0C7AC85D1}.Release|Any CPU.Build.0 = Release|Any CPU
{89975A38-C78B-4464-A04D-D63E8745062D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{89975A38-C78B-4464-A04D-D63E8745062D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{89975A38-C78B-4464-A04D-D63E8745062D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{89975A38-C78B-4464-A04D-D63E8745062D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE