Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions DataLayer.Core/Class1.cs

This file was deleted.

54 changes: 54 additions & 0 deletions DataLayer.Core/DataClasses/Concrete/Blog.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#region licence
// The MIT License (MIT)
//
// Filename: Blog.cs
// Date Created: 2014/05/20
//
// Copyright (c) 2014 Jon Smith (www.selectiveanalytics.com & www.thereformedprogrammer.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#endregion
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace DataLayer.Core.DataClasses.Concrete
{
public class Blog
{
public int BlogId { get; set; }

[MinLength(2)]
[MaxLength(64)]
[Required]
public string Name { get; set; }

Check warning on line 39 in DataLayer.Core/DataClasses/Concrete/Blog.cs

View workflow job for this annotation

GitHub Actions / build (8.0.x)

Non-nullable property 'Name' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

Check warning on line 39 in DataLayer.Core/DataClasses/Concrete/Blog.cs

View workflow job for this annotation

GitHub Actions / code-quality

Non-nullable property 'Name' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

[MaxLength(256)]
[Required]
[EmailAddress]
public string EmailAddress { get; set; }

Check warning on line 44 in DataLayer.Core/DataClasses/Concrete/Blog.cs

View workflow job for this annotation

GitHub Actions / build (8.0.x)

Non-nullable property 'EmailAddress' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

Check warning on line 44 in DataLayer.Core/DataClasses/Concrete/Blog.cs

View workflow job for this annotation

GitHub Actions / code-quality

Non-nullable property 'EmailAddress' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

public ICollection<Post> Posts { get; set; }

Check warning on line 46 in DataLayer.Core/DataClasses/Concrete/Blog.cs

View workflow job for this annotation

GitHub Actions / build (8.0.x)

Non-nullable property 'Posts' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

Check warning on line 46 in DataLayer.Core/DataClasses/Concrete/Blog.cs

View workflow job for this annotation

GitHub Actions / code-quality

Non-nullable property 'Posts' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

public override string ToString()
{
return string.Format("BlogId: {0}, Name: {1}, EmailAddress: {2}, NumPosts: {3}",
BlogId, Name, EmailAddress, Posts == null ? "null" : Posts.Count.ToString());
}
}
}
45 changes: 45 additions & 0 deletions DataLayer.Core/DataClasses/Concrete/Helpers/TrackUpdate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#region licence
// The MIT License (MIT)
//
// Filename: TrackUpdate.cs
// Date Created: 2014/05/20
//
// Copyright (c) 2014 Jon Smith (www.selectiveanalytics.com & www.thereformedprogrammer.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#endregion
using System;

namespace DataLayer.Core.DataClasses.Concrete.Helpers
{
public abstract class TrackUpdate
{
public DateTime LastUpdated { get; protected set; }

internal void UpdateTrackingInfo()
{
LastUpdated = DateTime.UtcNow;
}

protected TrackUpdate()
{
UpdateTrackingInfo();
}
}
}
76 changes: 76 additions & 0 deletions DataLayer.Core/DataClasses/Concrete/Post.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#region licence
// The MIT License (MIT)
//
// Filename: Post.cs
// Date Created: 2014/05/20
//
// Copyright (c) 2014 Jon Smith (www.selectiveanalytics.com & www.thereformedprogrammer.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#endregion
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using DataLayer.Core.DataClasses.Concrete.Helpers;

namespace DataLayer.Core.DataClasses.Concrete
{
public class Post : TrackUpdate, IValidatableObject
{
public int PostId { get; set; }

[MinLength(2), MaxLength(128)]
[Required]
public string Title { get; set; }

[Required]
public string Content { get; set; }

public int BlogId { get; set; }
public virtual Blog Blogger { get; set; }

public ICollection<Tag> Tags { get; set; }

public override string ToString()
{
return string.Format("PostId: {0}, Title: {1}, BlogId: {2}, Blogger: {3}, AllocatedTags: {4}",
PostId, Title, BlogId, Blogger == null ? "null" : Blogger.Name, Tags == null ? "null" : Tags.Count().ToString());
}

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (Tags != null && !Tags.Any())
yield return new ValidationResult("The post must have at least one Tag.", new[] { "AllocatedTags" });

if (Title.Contains("!"))
yield return new ValidationResult("Sorry, but you can't get too excited and include a ! in the title.", new[] { "Title" });
if (Title.EndsWith("?"))
yield return new ValidationResult("Sorry, but you can't ask a question, i.e. the title can't end with '?'.", new[] { "Title" });

if (Content.Contains(" sheep."))
yield return new ValidationResult("Sorry. Not allowed to end a sentance with 'sheep'.");
if (Content.Contains(" lamb."))
yield return new ValidationResult("Sorry. Not allowed to end a sentance with 'lamb'.");
if (Content.Contains(" cow."))
yield return new ValidationResult("Sorry. Not allowed to end a sentance with 'cow'.");
if (Content.Contains(" calf."))
yield return new ValidationResult("Sorry. Not allowed to end a sentance with 'calf'.");
}
}
}
52 changes: 52 additions & 0 deletions DataLayer.Core/DataClasses/Concrete/Tag.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#region licence
// The MIT License (MIT)
//
// Filename: Tag.cs
// Date Created: 2014/05/20
//
// Copyright (c) 2014 Jon Smith (www.selectiveanalytics.com & www.thereformedprogrammer.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#endregion
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace DataLayer.Core.DataClasses.Concrete
{
public class Tag
{
public int TagId { get; set; }

[MaxLength(64)]
[Required]
[RegularExpression(@"\w*", ErrorMessage = "The slug must not contain spaces or non-alphanumeric characters.")]
public string Slug { get; set; }

Check warning on line 39 in DataLayer.Core/DataClasses/Concrete/Tag.cs

View workflow job for this annotation

GitHub Actions / build (8.0.x)

Non-nullable property 'Slug' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

Check warning on line 39 in DataLayer.Core/DataClasses/Concrete/Tag.cs

View workflow job for this annotation

GitHub Actions / code-quality

Non-nullable property 'Slug' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

[MaxLength(128)]
[Required]
public string Name { get; set; }

Check warning on line 43 in DataLayer.Core/DataClasses/Concrete/Tag.cs

View workflow job for this annotation

GitHub Actions / build (8.0.x)

Non-nullable property 'Name' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

Check warning on line 43 in DataLayer.Core/DataClasses/Concrete/Tag.cs

View workflow job for this annotation

GitHub Actions / code-quality

Non-nullable property 'Name' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

public ICollection<Post> Posts { get; set; }

Check warning on line 45 in DataLayer.Core/DataClasses/Concrete/Tag.cs

View workflow job for this annotation

GitHub Actions / build (8.0.x)

Non-nullable property 'Posts' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

Check warning on line 45 in DataLayer.Core/DataClasses/Concrete/Tag.cs

View workflow job for this annotation

GitHub Actions / code-quality

Non-nullable property 'Posts' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

public override string ToString()
{
return string.Format("TagId: {0}, Name: {1}, Slug: {2}", TagId, Name, Slug);
}
}
}
125 changes: 125 additions & 0 deletions DataLayer.Core/DataClasses/SampleWebAppDbCore.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#region licence
// The MIT License (MIT)
//
// Filename: SampleWebAppDbCore.cs
// Date Created: 2014/05/20
//
// Copyright (c) 2014 Jon Smith (www.selectiveanalytics.com & www.thereformedprogrammer.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#endregion
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using DataLayer.Core.DataClasses.Concrete;
using DataLayer.Core.DataClasses.Concrete.Helpers;
using Microsoft.EntityFrameworkCore;

namespace DataLayer.Core.DataClasses
{
public class SampleWebAppDbCore : DbContext
{
public const string NameOfConnectionString = "SampleWebAppDb";

private static readonly string DefaultConnectionString =
@"Data Source=(localdb)\mssqllocaldb;Initial Catalog=SampleWebAppDb;MultipleActiveResultSets=True;Integrated Security=SSPI;Trusted_Connection=True";

private readonly string _connectionString;

public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
public DbSet<Tag> Tags { get; set; }

public SampleWebAppDbCore() : base()
{
_connectionString = DefaultConnectionString;
}

public SampleWebAppDbCore(DbContextOptions<SampleWebAppDbCore> options) : base(options)

Check warning on line 55 in DataLayer.Core/DataClasses/SampleWebAppDbCore.cs

View workflow job for this annotation

GitHub Actions / build (8.0.x)

Non-nullable field '_connectionString' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 55 in DataLayer.Core/DataClasses/SampleWebAppDbCore.cs

View workflow job for this annotation

GitHub Actions / code-quality

Non-nullable field '_connectionString' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.
{
}

public SampleWebAppDbCore(string connectionString) : base()
{
_connectionString = connectionString;
}

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer(_connectionString ?? DefaultConnectionString);
}
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);

modelBuilder.Entity<Tag>()
.HasIndex(t => t.Slug)
.IsUnique();

modelBuilder.Entity<Post>()
.HasOne(p => p.Blogger)
.WithMany(b => b.Posts)
.HasForeignKey(p => p.BlogId);

modelBuilder.Entity<Post>()
.HasMany(p => p.Tags)
.WithMany(t => t.Posts);
}

public override int SaveChanges()
{
HandleChangeTracking();
return base.SaveChanges();
}

public override int SaveChanges(bool acceptAllChangesOnSuccess)
{
HandleChangeTracking();
return base.SaveChanges(acceptAllChangesOnSuccess);
}

public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
{
HandleChangeTracking();
return base.SaveChangesAsync(cancellationToken);
}

public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default)
{
HandleChangeTracking();
return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
}

private void HandleChangeTracking()
{
foreach (var entity in ChangeTracker.Entries()
.Where(e => e.State == EntityState.Added || e.State == EntityState.Modified))
{
var trackUpdateClass = entity.Entity as TrackUpdate;
if (trackUpdateClass == null) continue;
trackUpdateClass.UpdateTrackingInfo();
}
}
}
}
21 changes: 19 additions & 2 deletions DataLayer.Core/DataLayer.Core.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="Startup\Internal\BlogsContentSimple.xml" />
<EmbeddedResource Include="Startup\Internal\BlogsContextMedium.xml" />
</ItemGroup>

</Project>
Loading