-
Notifications
You must be signed in to change notification settings - Fork 1
/
ApplicationDbContext.cs
104 lines (92 loc) · 4.07 KB
/
ApplicationDbContext.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
using BlazorWasmGrpcBlog.Server.Models;
using BlazorWasmGrpcBlog.Shared.Helpers;
using BlazorWasmGrpcBlog.Shared.Protos;
using IdentityServer4.EntityFramework.Options;
using Microsoft.AspNetCore.ApiAuthorization.IdentityServer;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
namespace BlazorWasmGrpcBlog.Server.Data
{
// Info
// SQLite DB
// When Proto/ Model Change
// Visual Studio:
// Delete /Server/Data/Migrations folder
// Delete /Server/Data/BlogDB.sqlite3
// Package Manager Console:
// Clear; Add-Migration InitialCreate -OutputDir "Data/Migrations"; Update-Database;
public class ApplicationDbContext : ApiAuthorizationDbContext<ApplicationUser>
{
public ApplicationDbContext(
DbContextOptions options,
IOptions<OperationalStoreOptions> operationalStoreOptions) : base(options, operationalStoreOptions)
{
}
public DbSet<Author> Authors { get; set; }
public DbSet<Post> Posts { get; set; }
public DbSet<PostExtended> PostsExtented { get; set; }
public DbSet<Tag> Tags { get; set; }
// Extra for testing/Learning
// See (gavilanch3) https://www.youtube.com/watch?v=yJAf5fKpGO
//public DbSet<PostsTags2> PostsTags2 { get; set; }
//public override int SaveChanges()
//{
// return base.SaveChanges();
//}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.LogTo(Console.WriteLine, LogLevel.Information) // LogLevel.Warning for production
.EnableSensitiveDataLogging(); // for debugging
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// From ON.NET Deep Dive in Many to Many Part 2
// See: https://channel9.msdn.com/Shows/On-NET/Deep-Dive-into-Many-to-Many-A-Tour-of-EF-Core-50-pt-2
modelBuilder
.Entity<Post>()
.HasMany(e => e.TagsInPostData)
.WithMany(e => e.PostsInTagData)
.UsingEntity<Dictionary<string, object>>(
"PostsTags", // (Join) Table Name.(Renames EF Core autogenerated 'PostTag' table to 'PostsTags' table)
// I had "TagId" & "PostId" switched, still the same outcome (stack overflow)
b => b.HasOne<Tag>().WithMany().HasForeignKey("TagId"), // Field Name.
b => b.HasOne<Post>().WithMany().HasForeignKey("PostId") // Field Name.
);
// Adding data to Many to Many Join Table 'PostsTags' now works because of just the 2 lines below.
// See: https://github.com/dotnet/efcore/issues/23703#issuecomment-758801618
modelBuilder.Entity<Post>().Navigation(e => e.TagsInPostData).HasField("tagsInPostData_");
modelBuilder.Entity<Tag>().Navigation(e => e.PostsInTagData).HasField("postsInTagData_");
// Extra for testing/Learning
// See (gavilanch3) https://www.youtube.com/watch?v=yJAf5fKpGO
//modelBuilder
// .Entity<Post>()
// .HasMany(t => t.TagsInPostData)
// .WithMany(p => p.PostsInTagData)
// .UsingEntity<PostsTags2>(
// pt => pt.HasOne(prop => prop.Tag).WithMany().HasForeignKey(prop => prop.TagId),
// pt => pt.HasOne(prop => prop.Post).WithMany().HasForeignKey(prop => prop.PostId),
// pt =>
// {
// pt.HasKey(prop => new { prop.TagId, prop.PostId });
// pt.Property(prop => prop.CreatedUtc).HasDefaultValueSql("CURRENT_TIMESTAMP");
// }
// );
// Code just for testing using a ValueConverter, see /Shared/Protos/blog.proto
var tsConverter = new ValueConverter<Google.Protobuf.WellKnownTypes.Timestamp, string>(
v => v == null ? null : v.ToDateTimeOffset().ToString(DtFormats.DbUtc), // UTC To DB
v => v == null ? null : Google.Protobuf.WellKnownTypes.Timestamp
.FromDateTimeOffset(DateTime.ParseExact(v, DtFormats.DbUtc, System.Globalization.CultureInfo.InvariantCulture)) // UTC From DB
);
modelBuilder.Entity<PostExtended>().Property(e => e.Ts).HasConversion(tsConverter);
modelBuilder.Entity<PostExtended>()
.HasKey(c => c.PostId);
modelBuilder.Entity<PostExtended>()
.Property(c => c.PostId)
.ValueGeneratedNever();
base.OnModelCreating(modelBuilder);
}
}
}