WIP on EF Core data context
This commit is contained in:
parent
69bc105e40
commit
8bc2cf0aa5
42
src/MyWebLog.Data/Category.cs
Normal file
42
src/MyWebLog.Data/Category.cs
Normal file
|
@ -0,0 +1,42 @@
|
|||
namespace MyWebLog.Data;
|
||||
|
||||
/// <summary>
|
||||
/// A category under which a post may be identfied
|
||||
/// </summary>
|
||||
public class Category
|
||||
{
|
||||
/// <summary>
|
||||
/// The ID of the category
|
||||
/// </summary>
|
||||
public string Id { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The displayed name
|
||||
/// </summary>
|
||||
public string Name { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The slug (used in category URLs)
|
||||
/// </summary>
|
||||
public string Slug { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// A longer description of the category
|
||||
/// </summary>
|
||||
public string? Description { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// The parent ID of this category (if a subcategory)
|
||||
/// </summary>
|
||||
public string? ParentId { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// The parent of this category (if a subcategory)
|
||||
/// </summary>
|
||||
public Category? Parent { get; set; } = default;
|
||||
|
||||
/// <summary>
|
||||
/// The posts assigned to this category
|
||||
/// </summary>
|
||||
public ICollection<Post> Posts { get; set; } = default!;
|
||||
}
|
62
src/MyWebLog.Data/Comment.cs
Normal file
62
src/MyWebLog.Data/Comment.cs
Normal file
|
@ -0,0 +1,62 @@
|
|||
namespace MyWebLog.Data;
|
||||
|
||||
/// <summary>
|
||||
/// A comment on a post
|
||||
/// </summary>
|
||||
public class Comment
|
||||
{
|
||||
/// <summary>
|
||||
/// The ID of the comment
|
||||
/// </summary>
|
||||
public string Id { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The ID of the post to which this comment applies
|
||||
/// </summary>
|
||||
public string PostId { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The post to which this comment applies
|
||||
/// </summary>
|
||||
public Post Post { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The ID of the comment to which this comment is a reply
|
||||
/// </summary>
|
||||
public string? InReplyToId { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// The comment to which this comment is a reply
|
||||
/// </summary>
|
||||
public Comment? InReplyTo { get; set; } = default;
|
||||
|
||||
/// <summary>
|
||||
/// The name of the commentor
|
||||
/// </summary>
|
||||
public string Name { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The e-mail address of the commentor
|
||||
/// </summary>
|
||||
public string Email { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The URL of the commentor's personal website
|
||||
/// </summary>
|
||||
public string? Url { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// The status of the comment
|
||||
/// </summary>
|
||||
public CommentStatus Status { get; set; } = CommentStatus.Pending;
|
||||
|
||||
/// <summary>
|
||||
/// When the comment was posted
|
||||
/// </summary>
|
||||
public DateTime PostedOn { get; set; } = DateTime.UtcNow;
|
||||
|
||||
/// <summary>
|
||||
/// The text of the comment
|
||||
/// </summary>
|
||||
public string Text { get; set; } = "";
|
||||
}
|
47
src/MyWebLog.Data/Enums.cs
Normal file
47
src/MyWebLog.Data/Enums.cs
Normal file
|
@ -0,0 +1,47 @@
|
|||
namespace MyWebLog.Data;
|
||||
|
||||
/// <summary>
|
||||
/// The source format for a revision
|
||||
/// </summary>
|
||||
public enum RevisionSource
|
||||
{
|
||||
/// <summary>Markdown text</summary>
|
||||
Markdown,
|
||||
/// <summary>HTML</summary>
|
||||
Html
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A level of authorization for a given web log
|
||||
/// </summary>
|
||||
public enum AuthorizationLevel
|
||||
{
|
||||
/// <summary>The user may administer all aspects of a web log</summary>
|
||||
Administrator,
|
||||
/// <summary>The user is a known user of a web log</summary>
|
||||
User
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Statuses for posts
|
||||
/// </summary>
|
||||
public enum PostStatus
|
||||
{
|
||||
/// <summary>The post should not be publicly available</summary>
|
||||
Draft,
|
||||
/// <summary>The post is publicly viewable</summary>
|
||||
Published
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Statuses for post comments
|
||||
/// </summary>
|
||||
public enum CommentStatus
|
||||
{
|
||||
/// <summary>The comment is approved</summary>
|
||||
Approved,
|
||||
/// <summary>The comment has yet to be approved</summary>
|
||||
Pending,
|
||||
/// <summary>The comment was unsolicited and unwelcome</summary>
|
||||
Spam
|
||||
}
|
9
src/MyWebLog.Data/MyWebLog.Data.csproj
Normal file
9
src/MyWebLog.Data/MyWebLog.Data.csproj
Normal file
|
@ -0,0 +1,9 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
62
src/MyWebLog.Data/Page.cs
Normal file
62
src/MyWebLog.Data/Page.cs
Normal file
|
@ -0,0 +1,62 @@
|
|||
namespace MyWebLog.Data;
|
||||
|
||||
/// <summary>
|
||||
/// A page (text not associated with a date/time)
|
||||
/// </summary>
|
||||
public class Page
|
||||
{
|
||||
/// <summary>
|
||||
/// The ID of this page
|
||||
/// </summary>
|
||||
public string Id { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The ID of the author of this page
|
||||
/// </summary>
|
||||
public string AuthorId { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The author of this page
|
||||
/// </summary>
|
||||
public WebLogUser Author { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The title of the page
|
||||
/// </summary>
|
||||
public string Title { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The link at which this page is displayed
|
||||
/// </summary>
|
||||
public string Permalink { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The instant this page was published
|
||||
/// </summary>
|
||||
public DateTime PublishedOn { get; set; } = DateTime.MinValue;
|
||||
|
||||
/// <summary>
|
||||
/// The instant this page was last updated
|
||||
/// </summary>
|
||||
public DateTime UpdatedOn { get; set; } = DateTime.MinValue;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this page shows as part of the web log's navigation
|
||||
/// </summary>
|
||||
public bool ShowInPageList { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// The current text of the page
|
||||
/// </summary>
|
||||
public string Text { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Permalinks at which this page may have been previously served (useful for migrated content)
|
||||
/// </summary>
|
||||
public ICollection<PagePermalink> PriorPermalinks { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Revisions of this page
|
||||
/// </summary>
|
||||
public ICollection<PageRevision> Revisions { get; set; } = default!;
|
||||
}
|
49
src/MyWebLog.Data/Permalink.cs
Normal file
49
src/MyWebLog.Data/Permalink.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
namespace MyWebLog.Data;
|
||||
|
||||
/// <summary>
|
||||
/// A permalink which a post or page used to have
|
||||
/// </summary>
|
||||
public abstract class Permalink
|
||||
{
|
||||
/// <summary>
|
||||
/// The ID of this permalink
|
||||
/// </summary>
|
||||
public string Id { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The link
|
||||
/// </summary>
|
||||
public string Url { get; set; } = "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A prior permalink for a page
|
||||
/// </summary>
|
||||
public class PagePermalink : Permalink
|
||||
{
|
||||
/// <summary>
|
||||
/// The ID of the page to which this permalink belongs
|
||||
/// </summary>
|
||||
public string PageId { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The page to which this permalink belongs
|
||||
/// </summary>
|
||||
public Page Page { get; set; } = default!;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A prior permalink for a post
|
||||
/// </summary>
|
||||
public class PostPermalink : Permalink
|
||||
{
|
||||
/// <summary>
|
||||
/// The ID of the post to which this permalink belongs
|
||||
/// </summary>
|
||||
public string PostId { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The post to which this permalink belongs
|
||||
/// </summary>
|
||||
public Post Post { get; set; } = default!;
|
||||
}
|
72
src/MyWebLog.Data/Post.cs
Normal file
72
src/MyWebLog.Data/Post.cs
Normal file
|
@ -0,0 +1,72 @@
|
|||
namespace MyWebLog.Data;
|
||||
|
||||
/// <summary>
|
||||
/// A web log post
|
||||
/// </summary>
|
||||
public class Post
|
||||
{
|
||||
/// <summary>
|
||||
/// The ID of this post
|
||||
/// </summary>
|
||||
public string Id { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The ID of the author of this post
|
||||
/// </summary>
|
||||
public string AuthorId { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The author of the post
|
||||
/// </summary>
|
||||
public WebLogUser Author { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The status
|
||||
/// </summary>
|
||||
public PostStatus Status { get; set; } = PostStatus.Draft;
|
||||
|
||||
/// <summary>
|
||||
/// The title
|
||||
/// </summary>
|
||||
public string Title { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The link at which the post resides
|
||||
/// </summary>
|
||||
public string Permalink { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The instant on which the post was originally published
|
||||
/// </summary>
|
||||
public DateTime? PublishedOn { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// The instant on which the post was last updated
|
||||
/// </summary>
|
||||
public DateTime UpdatedOn { get; set; } = DateTime.MinValue;
|
||||
|
||||
/// <summary>
|
||||
/// The text of the post in HTML (ready to display) format
|
||||
/// </summary>
|
||||
public string Text { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The Ids of the categories to which this is assigned
|
||||
/// </summary>
|
||||
public ICollection<Category> Categories { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The tags for the post
|
||||
/// </summary>
|
||||
public ICollection<Tag> Tags { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Permalinks at which this post may have been previously served (useful for migrated content)
|
||||
/// </summary>
|
||||
public ICollection<PostPermalink> PriorPermalinks { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The revisions for this post
|
||||
/// </summary>
|
||||
public ICollection<PostRevision> Revisions { get; set; } = default!;
|
||||
}
|
59
src/MyWebLog.Data/Revision.cs
Normal file
59
src/MyWebLog.Data/Revision.cs
Normal file
|
@ -0,0 +1,59 @@
|
|||
namespace MyWebLog.Data;
|
||||
|
||||
/// <summary>
|
||||
/// A revision of a page or post
|
||||
/// </summary>
|
||||
public abstract class Revision
|
||||
{
|
||||
/// <summary>
|
||||
/// The ID of this revision
|
||||
/// </summary>
|
||||
public string Id { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// When this revision was saved
|
||||
/// </summary>
|
||||
public DateTime AsOf { get; set; } = DateTime.UtcNow;
|
||||
|
||||
/// <summary>
|
||||
/// The source language (Markdown or HTML)
|
||||
/// </summary>
|
||||
public RevisionSource SourceType { get; set; } = RevisionSource.Html;
|
||||
|
||||
/// <summary>
|
||||
/// The text of the revision
|
||||
/// </summary>
|
||||
public string Text { get; set; } = "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A revision of a page
|
||||
/// </summary>
|
||||
public class PageRevision : Revision
|
||||
{
|
||||
/// <summary>
|
||||
/// The ID of the page to which this revision belongs
|
||||
/// </summary>
|
||||
public string PageId { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The page to which this revision belongs
|
||||
/// </summary>
|
||||
public Page Page { get; set; } = default!;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A revision of a post
|
||||
/// </summary>
|
||||
public class PostRevision : Revision
|
||||
{
|
||||
/// <summary>
|
||||
/// The ID of the post to which this revision applies
|
||||
/// </summary>
|
||||
public string PostId { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The post to which this revision applies
|
||||
/// </summary>
|
||||
public Post Post { get; set; } = default!;
|
||||
}
|
17
src/MyWebLog.Data/Tag.cs
Normal file
17
src/MyWebLog.Data/Tag.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
namespace MyWebLog.Data;
|
||||
|
||||
/// <summary>
|
||||
/// A tag
|
||||
/// </summary>
|
||||
public class Tag
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the tag
|
||||
/// </summary>
|
||||
public string Name { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The posts with this tag assigned
|
||||
/// </summary>
|
||||
public ICollection<Post> Posts { get; set; } = default!;
|
||||
}
|
69
src/MyWebLog.Data/WebLogDbContext.cs
Normal file
69
src/MyWebLog.Data/WebLogDbContext.cs
Normal file
|
@ -0,0 +1,69 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace MyWebLog.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Data context for web log data
|
||||
/// </summary>
|
||||
public sealed class WebLogDbContext : DbContext
|
||||
{
|
||||
/// <summary>
|
||||
/// The categories for the web log
|
||||
/// </summary>
|
||||
public DbSet<Category> Categories { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Comments on posts
|
||||
/// </summary>
|
||||
public DbSet<Comment> Comments { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Pages
|
||||
/// </summary>
|
||||
public DbSet<Page> Pages { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Web log posts
|
||||
/// </summary>
|
||||
public DbSet<Post> Posts { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Post tags
|
||||
/// </summary>
|
||||
public DbSet<Tag> Tags { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The users of the web log
|
||||
/// </summary>
|
||||
public DbSet<WebLogUser> Users { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The details for the web log
|
||||
/// </summary>
|
||||
public DbSet<WebLogDetails> WebLogDetails { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="options">Configuration options</param>
|
||||
public WebLogDbContext(DbContextOptions<WebLogDbContext> options) : base(options) { }
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
base.OnModelCreating(modelBuilder);
|
||||
|
||||
// Tag and WebLogDetails use Name as its ID
|
||||
modelBuilder.Entity<Tag>().HasKey(t => t.Name);
|
||||
modelBuilder.Entity<WebLogDetails>().HasKey(wld => wld.Name);
|
||||
|
||||
// Index slugs and links
|
||||
modelBuilder.Entity<Category>().HasIndex(c => c.Slug);
|
||||
modelBuilder.Entity<Page>().HasIndex(p => p.Permalink);
|
||||
modelBuilder.Entity<Post>().HasIndex(p => p.Permalink);
|
||||
|
||||
// Link "author" to "user"
|
||||
modelBuilder.Entity<Page>().HasOne(p => p.Author).WithMany(wbu => wbu.Pages).HasForeignKey(p => p.AuthorId);
|
||||
modelBuilder.Entity<Post>().HasOne(p => p.Author).WithMany(wbu => wbu.Posts).HasForeignKey(p => p.AuthorId);
|
||||
}
|
||||
}
|
37
src/MyWebLog.Data/WebLogDetails.cs
Normal file
37
src/MyWebLog.Data/WebLogDetails.cs
Normal file
|
@ -0,0 +1,37 @@
|
|||
namespace MyWebLog.Data;
|
||||
|
||||
/// <summary>
|
||||
/// The details about a web log
|
||||
/// </summary>
|
||||
public class WebLogDetails
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the web log
|
||||
/// </summary>
|
||||
public string Name { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// A subtitle for the web log
|
||||
/// </summary>
|
||||
public string? Subtitle { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// The default page ("posts" or a page Id)
|
||||
/// </summary>
|
||||
public string DefaultPage { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The path of the theme (within /views/themes)
|
||||
/// </summary>
|
||||
public string ThemePath { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The URL base
|
||||
/// </summary>
|
||||
public string UrlBase { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The time zone in which dates/times should be displayed
|
||||
/// </summary>
|
||||
public string TimeZone { get; set; } = "";
|
||||
}
|
57
src/MyWebLog.Data/WebLogUser.cs
Normal file
57
src/MyWebLog.Data/WebLogUser.cs
Normal file
|
@ -0,0 +1,57 @@
|
|||
namespace MyWebLog.Data;
|
||||
|
||||
/// <summary>
|
||||
/// A user of the web log
|
||||
/// </summary>
|
||||
public class WebLogUser
|
||||
{
|
||||
/// <summary>
|
||||
/// The ID of the user
|
||||
/// </summary>
|
||||
public string Id { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The user name (e-mail address)
|
||||
/// </summary>
|
||||
public string UserName { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The user's first name
|
||||
/// </summary>
|
||||
public string FirstName { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The user's last name
|
||||
/// </summary>
|
||||
public string LastName { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The user's preferred name
|
||||
/// </summary>
|
||||
public string PreferredName { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The hash of the user's password
|
||||
/// </summary>
|
||||
public string PasswordHash { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Salt used to calculate the user's password hash
|
||||
/// </summary>
|
||||
public Guid Salt { get; set; } = Guid.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// The URL of the user's personal site
|
||||
/// </summary>
|
||||
public string? Url { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// Pages written by this author
|
||||
/// </summary>
|
||||
public ICollection<Page> Pages { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Posts written by this author
|
||||
/// </summary>
|
||||
public ICollection<Post> Posts { get; set; } = default!;
|
||||
}
|
31
src/MyWebLog.sln
Normal file
31
src/MyWebLog.sln
Normal file
|
@ -0,0 +1,31 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.1.32210.238
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "MyWebLog", "MyWebLog\MyWebLog.fsproj", "{2E5E2346-25FE-4CBD-89AA-6148A33DE09C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyWebLog.Data", "MyWebLog.Data\MyWebLog.Data.csproj", "{0177C744-F913-4352-A0EC-478B4B0388C3}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{2E5E2346-25FE-4CBD-89AA-6148A33DE09C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2E5E2346-25FE-4CBD-89AA-6148A33DE09C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2E5E2346-25FE-4CBD-89AA-6148A33DE09C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2E5E2346-25FE-4CBD-89AA-6148A33DE09C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0177C744-F913-4352-A0EC-478B4B0388C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0177C744-F913-4352-A0EC-478B4B0388C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0177C744-F913-4352-A0EC-478B4B0388C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0177C744-F913-4352-A0EC-478B4B0388C3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {70EEF0F4-8709-44A8-AD9B-24D1EB84CFB4}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
Loading…
Reference in New Issue
Block a user