PI06 i PI06-1. Docker definitions for MSSQL and Postgres. Data seeder/generator for countries and people. Entity Framework example with variants for Postgres and MSSQL
This commit is contained in:
25
DataAccess/DataAccess.sln
Normal file
25
DataAccess/DataAccess.sln
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 18
|
||||
VisualStudioVersion = 18.5.11709.299
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EF_Demo", "EF_Demo\EF_Demo.csproj", "{26C4670D-F5D0-420C-8730-F76E53BAA639}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{26C4670D-F5D0-420C-8730-F76E53BAA639}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{26C4670D-F5D0-420C-8730-F76E53BAA639}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{26C4670D-F5D0-420C-8730-F76E53BAA639}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{26C4670D-F5D0-420C-8730-F76E53BAA639}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {2C6663EA-3869-40E6-8F2A-0F122E9CDE02}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
32
DataAccess/EF_Demo/DISetup.cs
Normal file
32
DataAccess/EF_Demo/DISetup.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace EF_Demo;
|
||||
|
||||
internal class DISetup
|
||||
{
|
||||
public static ServiceProvider BuildDI()
|
||||
{
|
||||
var configuration = new ConfigurationBuilder()
|
||||
.AddJsonFile("appsettings.json")
|
||||
.AddUserSecrets<Program>()
|
||||
.Build();
|
||||
|
||||
IServiceCollection services = new ServiceCollection();
|
||||
|
||||
var provider = services.AddLogging(configure => {
|
||||
configure.AddConfiguration(configuration.GetSection("Logging"));
|
||||
configure.AddConsole();
|
||||
})
|
||||
.AddDbContext<Data.MSSQL.EventsContext>(options => {
|
||||
options.UseSqlServer(configuration.GetConnectionString("EventsMssql"));
|
||||
}, contextLifetime: ServiceLifetime.Transient)
|
||||
.AddDbContext<Data.Postgres.EventsContext>(options => {
|
||||
options.UseNpgsql(configuration.GetConnectionString("EventsPostgres"));
|
||||
}, contextLifetime: ServiceLifetime.Transient)
|
||||
.BuildServiceProvider();
|
||||
return provider;
|
||||
}
|
||||
}
|
||||
143
DataAccess/EF_Demo/Data/MSSQL/EventsContext.cs
Normal file
143
DataAccess/EF_Demo/Data/MSSQL/EventsContext.cs
Normal file
@@ -0,0 +1,143 @@
|
||||
// <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated>
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using EF_Demo.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace EF_Demo.Data.MSSQL;
|
||||
|
||||
public partial class EventsContext : DbContext
|
||||
{
|
||||
public EventsContext(DbContextOptions<EventsContext> options)
|
||||
: base(options)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual DbSet<Country> Countries { get; set; }
|
||||
|
||||
public virtual DbSet<Event> Events { get; set; }
|
||||
|
||||
public virtual DbSet<Person> People { get; set; }
|
||||
|
||||
public virtual DbSet<Registration> Registrations { get; set; }
|
||||
|
||||
public virtual DbSet<Sport> Sports { get; set; }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<Country>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Code);
|
||||
|
||||
entity.ToTable("Country");
|
||||
|
||||
entity.HasIndex(e => e.Name, "UQ_Country_Name").IsUnique();
|
||||
|
||||
entity.Property(e => e.Code)
|
||||
.HasMaxLength(3)
|
||||
.IsUnicode(false);
|
||||
entity.Property(e => e.Alpha3)
|
||||
.HasMaxLength(3)
|
||||
.IsUnicode(false)
|
||||
.IsFixedLength();
|
||||
entity.Property(e => e.Name)
|
||||
.HasMaxLength(100)
|
||||
.IsUnicode(false);
|
||||
});
|
||||
|
||||
modelBuilder.Entity<Event>(entity =>
|
||||
{
|
||||
entity.ToTable("Event");
|
||||
|
||||
entity.Property(e => e.Name)
|
||||
.HasMaxLength(150)
|
||||
.IsUnicode(false);
|
||||
});
|
||||
|
||||
modelBuilder.Entity<Person>(entity =>
|
||||
{
|
||||
entity.ToTable("Person");
|
||||
|
||||
entity.HasIndex(e => new { e.DocumentNumber, e.CountryCode }, "UQ_Person_DocumentNumber_CountryCode").IsUnique();
|
||||
|
||||
entity.Property(e => e.AddressCountry)
|
||||
.HasMaxLength(100)
|
||||
.IsUnicode(false);
|
||||
entity.Property(e => e.AddressLine)
|
||||
.HasMaxLength(200)
|
||||
.IsUnicode(false);
|
||||
entity.Property(e => e.City)
|
||||
.HasMaxLength(100)
|
||||
.IsUnicode(false);
|
||||
entity.Property(e => e.ContactPhone)
|
||||
.HasMaxLength(50)
|
||||
.IsUnicode(false);
|
||||
entity.Property(e => e.CountryCode)
|
||||
.HasMaxLength(3)
|
||||
.IsUnicode(false);
|
||||
entity.Property(e => e.DocumentNumber)
|
||||
.HasMaxLength(50)
|
||||
.IsUnicode(false);
|
||||
entity.Property(e => e.Email)
|
||||
.HasMaxLength(255)
|
||||
.IsUnicode(false);
|
||||
entity.Property(e => e.FirstName)
|
||||
.HasMaxLength(100)
|
||||
.IsUnicode(false);
|
||||
entity.Property(e => e.FirstNameTranscription)
|
||||
.HasMaxLength(100)
|
||||
.IsUnicode(false);
|
||||
entity.Property(e => e.LastName)
|
||||
.HasMaxLength(100)
|
||||
.IsUnicode(false);
|
||||
entity.Property(e => e.LastNameTranscription)
|
||||
.HasMaxLength(100)
|
||||
.IsUnicode(false);
|
||||
entity.Property(e => e.PostalCode)
|
||||
.HasMaxLength(20)
|
||||
.IsUnicode(false);
|
||||
|
||||
entity.HasOne(d => d.CountryCodeNavigation).WithMany(p => p.People)
|
||||
.HasForeignKey(d => d.CountryCode)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("FK_Person_Country");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<Registration>(entity =>
|
||||
{
|
||||
entity.ToTable("Registration");
|
||||
|
||||
entity.HasIndex(e => new { e.PersonId, e.SportId, e.EventId }, "UQ_Registration_PersonId_SportId_EventId").IsUnique();
|
||||
|
||||
entity.Property(e => e.RegisteredAt).HasDefaultValueSql("(sysdatetime())", "DF_Registration_RegisteredAt");
|
||||
|
||||
entity.HasOne(d => d.Event).WithMany(p => p.Registrations)
|
||||
.HasForeignKey(d => d.EventId)
|
||||
.HasConstraintName("FK_Registration_Event");
|
||||
|
||||
entity.HasOne(d => d.Person).WithMany(p => p.Registrations)
|
||||
.HasForeignKey(d => d.PersonId)
|
||||
.HasConstraintName("FK_Registration_Person");
|
||||
|
||||
entity.HasOne(d => d.Sport).WithMany(p => p.Registrations)
|
||||
.HasForeignKey(d => d.SportId)
|
||||
.HasConstraintName("FK_Registration_Sport");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<Sport>(entity =>
|
||||
{
|
||||
entity.ToTable("Sport");
|
||||
|
||||
entity.HasIndex(e => e.Name, "UQ_Sport_Name").IsUnique();
|
||||
|
||||
entity.Property(e => e.Name)
|
||||
.HasMaxLength(100)
|
||||
.IsUnicode(false);
|
||||
});
|
||||
|
||||
OnModelCreatingPartial(modelBuilder);
|
||||
}
|
||||
|
||||
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
|
||||
}
|
||||
166
DataAccess/EF_Demo/Data/Postgres/EventsContext.cs
Normal file
166
DataAccess/EF_Demo/Data/Postgres/EventsContext.cs
Normal file
@@ -0,0 +1,166 @@
|
||||
// <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated>
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using EF_Demo.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace EF_Demo.Data.Postgres;
|
||||
|
||||
public partial class EventsContext : DbContext
|
||||
{
|
||||
public EventsContext(DbContextOptions<EventsContext> options)
|
||||
: base(options)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual DbSet<Country> Countries { get; set; }
|
||||
|
||||
public virtual DbSet<Event> Events { get; set; }
|
||||
|
||||
public virtual DbSet<Person> People { get; set; }
|
||||
|
||||
public virtual DbSet<Registration> Registrations { get; set; }
|
||||
|
||||
public virtual DbSet<Sport> Sports { get; set; }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<Country>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Code).HasName("country_pkey");
|
||||
|
||||
entity.ToTable("country");
|
||||
|
||||
entity.HasIndex(e => e.Name, "country_name_key").IsUnique();
|
||||
|
||||
entity.Property(e => e.Code)
|
||||
.HasMaxLength(3)
|
||||
.HasColumnName("code");
|
||||
entity.Property(e => e.Alpha3)
|
||||
.HasMaxLength(3)
|
||||
.IsFixedLength()
|
||||
.HasColumnName("alpha3");
|
||||
entity.Property(e => e.Name)
|
||||
.HasMaxLength(100)
|
||||
.HasColumnName("name");
|
||||
entity.Property(e => e.Translations)
|
||||
.HasColumnType("jsonb")
|
||||
.HasColumnName("translations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<Event>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("event_pkey");
|
||||
|
||||
entity.ToTable("event");
|
||||
|
||||
entity.Property(e => e.Id).HasColumnName("id");
|
||||
entity.Property(e => e.EventDate).HasColumnName("event_date");
|
||||
entity.Property(e => e.Name)
|
||||
.HasMaxLength(150)
|
||||
.HasColumnName("name");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<Person>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("person_pkey");
|
||||
|
||||
entity.ToTable("person");
|
||||
|
||||
entity.HasIndex(e => new { e.DocumentNumber, e.CountryCode }, "person_document_number_country_code_key").IsUnique();
|
||||
|
||||
entity.Property(e => e.Id).HasColumnName("id");
|
||||
entity.Property(e => e.AddressCountry)
|
||||
.HasMaxLength(100)
|
||||
.HasColumnName("address_country");
|
||||
entity.Property(e => e.AddressLine)
|
||||
.HasMaxLength(200)
|
||||
.HasColumnName("address_line");
|
||||
entity.Property(e => e.BirthDate).HasColumnName("birth_date");
|
||||
entity.Property(e => e.City)
|
||||
.HasMaxLength(100)
|
||||
.HasColumnName("city");
|
||||
entity.Property(e => e.ContactPhone)
|
||||
.HasMaxLength(50)
|
||||
.HasColumnName("contact_phone");
|
||||
entity.Property(e => e.CountryCode)
|
||||
.HasMaxLength(3)
|
||||
.HasColumnName("country_code");
|
||||
entity.Property(e => e.DocumentNumber)
|
||||
.HasMaxLength(50)
|
||||
.HasColumnName("document_number");
|
||||
entity.Property(e => e.Email)
|
||||
.HasMaxLength(255)
|
||||
.HasColumnName("email");
|
||||
entity.Property(e => e.FirstName)
|
||||
.HasMaxLength(100)
|
||||
.HasColumnName("first_name");
|
||||
entity.Property(e => e.FirstNameTranscription)
|
||||
.HasMaxLength(100)
|
||||
.HasColumnName("first_name_transcription");
|
||||
entity.Property(e => e.LastName)
|
||||
.HasMaxLength(100)
|
||||
.HasColumnName("last_name");
|
||||
entity.Property(e => e.LastNameTranscription)
|
||||
.HasMaxLength(100)
|
||||
.HasColumnName("last_name_transcription");
|
||||
entity.Property(e => e.PostalCode)
|
||||
.HasMaxLength(20)
|
||||
.HasColumnName("postal_code");
|
||||
|
||||
entity.HasOne(d => d.CountryCodeNavigation).WithMany(p => p.People)
|
||||
.HasForeignKey(d => d.CountryCode)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("person_country_code_fkey");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<Registration>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("registration_pkey");
|
||||
|
||||
entity.ToTable("registration");
|
||||
|
||||
entity.HasIndex(e => new { e.PersonId, e.SportId, e.EventId }, "registration_person_id_sport_id_event_id_key").IsUnique();
|
||||
|
||||
entity.Property(e => e.Id).HasColumnName("id");
|
||||
entity.Property(e => e.EventId).HasColumnName("event_id");
|
||||
entity.Property(e => e.PersonId).HasColumnName("person_id");
|
||||
entity.Property(e => e.RegisteredAt)
|
||||
.HasDefaultValueSql("CURRENT_TIMESTAMP")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnName("registered_at");
|
||||
entity.Property(e => e.SportId).HasColumnName("sport_id");
|
||||
|
||||
entity.HasOne(d => d.Event).WithMany(p => p.Registrations)
|
||||
.HasForeignKey(d => d.EventId)
|
||||
.HasConstraintName("registration_event_id_fkey");
|
||||
|
||||
entity.HasOne(d => d.Person).WithMany(p => p.Registrations)
|
||||
.HasForeignKey(d => d.PersonId)
|
||||
.HasConstraintName("registration_person_id_fkey");
|
||||
|
||||
entity.HasOne(d => d.Sport).WithMany(p => p.Registrations)
|
||||
.HasForeignKey(d => d.SportId)
|
||||
.HasConstraintName("registration_sport_id_fkey");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<Sport>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("sport_pkey");
|
||||
|
||||
entity.ToTable("sport");
|
||||
|
||||
entity.HasIndex(e => e.Name, "sport_name_key").IsUnique();
|
||||
|
||||
entity.Property(e => e.Id).HasColumnName("id");
|
||||
entity.Property(e => e.Name)
|
||||
.HasMaxLength(100)
|
||||
.HasColumnName("name");
|
||||
});
|
||||
|
||||
OnModelCreatingPartial(modelBuilder);
|
||||
}
|
||||
|
||||
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
|
||||
}
|
||||
110
DataAccess/EF_Demo/Demo.cs
Normal file
110
DataAccess/EF_Demo/Demo.cs
Normal file
@@ -0,0 +1,110 @@
|
||||
#if POSTGRES
|
||||
using EF_Demo.Data.Postgres;
|
||||
#else
|
||||
using EF_Demo.Data.MSSQL;
|
||||
#endif
|
||||
|
||||
using EF_Demo.Models;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace EF_Demo;
|
||||
|
||||
internal class Demo
|
||||
{
|
||||
internal static int? AddEvent(IServiceProvider serviceProvider, string eventName, DateOnly eventDate)
|
||||
{
|
||||
ILogger logger = serviceProvider.GetRequiredService<ILogger<Demo>>();
|
||||
try
|
||||
{
|
||||
using var ctx = serviceProvider.GetRequiredService<EventsContext>();
|
||||
Event @event = new()
|
||||
{
|
||||
Name = eventName,
|
||||
EventDate = eventDate
|
||||
};
|
||||
ctx.Add(@event); //or ctx.Events.Add(@event) or ctx.Set<Event>().Add(@event);
|
||||
ctx.SaveChanges();
|
||||
logger.LogInformation($"Event {eventName} successfully added with id {@event.Id}");
|
||||
return @event.Id;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
logger.LogError($"Error adding event #{eventName}: {exc.CompleteExceptionMessage()}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void DeleteEvent(IServiceProvider serviceProvider, int eventId)
|
||||
{
|
||||
ILogger logger = serviceProvider.GetRequiredService<ILogger<Demo>>();
|
||||
try
|
||||
{
|
||||
using var ctx = serviceProvider.GetRequiredService<EventsContext>();
|
||||
Event? @event = ctx.Events.Find(eventId);
|
||||
if (@event != null)
|
||||
{
|
||||
ctx.Remove(@event); //or ctx.Entry(product).State = EntityState.Deleted;
|
||||
ctx.SaveChanges();
|
||||
logger.LogInformation($"Event {@event.Name} deleted");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogWarning($"Event #{eventId} does not exists");
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
logger.LogError($"Error deleting event #{eventId}: {exc.CompleteExceptionMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
internal static void PostponeEvent(IServiceProvider serviceProvider, int eventId, int days)
|
||||
{
|
||||
ILogger logger = serviceProvider.GetRequiredService<ILogger<Demo>>();
|
||||
try
|
||||
{
|
||||
using var ctx = serviceProvider.GetRequiredService<EventsContext>();
|
||||
Event? @event = ctx.Events.Find(eventId);
|
||||
if (@event != null)
|
||||
{
|
||||
@event.EventDate = @event.EventDate.AddDays(days);
|
||||
ctx.SaveChanges();
|
||||
logger.LogInformation($"Event {@event.Name} postoponed to {@event.EventDate:dd.MM.yyyy.}");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger?.LogWarning($"Event #{eventId} does not exists");
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
logger?.LogError($"Error trying to change evenbt #{eventId}: {exc.CompleteExceptionMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Print all people born in the provided year, ordered by country, and then by transliterated last name, and first name
|
||||
/// query is projected to an anonymous class
|
||||
/// </summary>
|
||||
internal static void PrintPeople(IServiceProvider serviceProvider, int year)
|
||||
{
|
||||
using var ctx = serviceProvider.GetRequiredService<EventsContext>();
|
||||
var query = ctx.People
|
||||
.Where(p => p.BirthDate.Year == year)
|
||||
.OrderBy(p => p.CountryCodeNavigation.Name)
|
||||
.ThenBy(p => p.LastNameTranscription)
|
||||
.ThenBy(p => p.FirstNameTranscription)
|
||||
.Select(p => new
|
||||
{
|
||||
p.FirstName, p.LastName,
|
||||
p.FirstNameTranscription, p.LastNameTranscription,
|
||||
p.BirthDate,
|
||||
Country = p.CountryCodeNavigation.Name
|
||||
});
|
||||
foreach (var p in query)
|
||||
{
|
||||
Console.WriteLine($"{p.FirstName} {p.LastName} ({p.FirstNameTranscription} {p.LastNameTranscription}), {p.Country} {p.BirthDate:dd.MM.yyyy.}");
|
||||
}
|
||||
}
|
||||
}
|
||||
35
DataAccess/EF_Demo/EF_Demo.csproj
Normal file
35
DataAccess/EF_Demo/EF_Demo.csproj
Normal file
@@ -0,0 +1,35 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<UserSecretsId>PI</UserSecretsId>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DefineConstants>$(DefineConstants);POSTGRES</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.6">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="10.0.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="10.0.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="10.0.6" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="appsettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
18
DataAccess/EF_Demo/ExceptionExtensions.cs
Normal file
18
DataAccess/EF_Demo/ExceptionExtensions.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System.Text;
|
||||
|
||||
namespace EF_Demo;
|
||||
|
||||
public static class ExceptionExtensions
|
||||
{
|
||||
public static string CompleteExceptionMessage(this Exception exc)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(exc.Message);
|
||||
while (exc.InnerException != null)
|
||||
{
|
||||
exc = exc.InnerException;
|
||||
sb.AppendLine();
|
||||
sb.Append(exc.Message);
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
19
DataAccess/EF_Demo/Models/Country.cs
Normal file
19
DataAccess/EF_Demo/Models/Country.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
// <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated>
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace EF_Demo.Models;
|
||||
|
||||
public partial class Country
|
||||
{
|
||||
public string Code { get; set; } = null!;
|
||||
|
||||
public string Alpha3 { get; set; } = null!;
|
||||
|
||||
public string Name { get; set; } = null!;
|
||||
|
||||
public string? Translations { get; set; }
|
||||
|
||||
public virtual ICollection<Person> People { get; set; } = new List<Person>();
|
||||
}
|
||||
17
DataAccess/EF_Demo/Models/Event.cs
Normal file
17
DataAccess/EF_Demo/Models/Event.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
// <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated>
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace EF_Demo.Models;
|
||||
|
||||
public partial class Event
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Name { get; set; } = null!;
|
||||
|
||||
public DateOnly EventDate { get; set; }
|
||||
|
||||
public virtual ICollection<Registration> Registrations { get; set; } = new List<Registration>();
|
||||
}
|
||||
41
DataAccess/EF_Demo/Models/Person.cs
Normal file
41
DataAccess/EF_Demo/Models/Person.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
// <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated>
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace EF_Demo.Models;
|
||||
|
||||
public partial class Person
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public string FirstName { get; set; } = null!;
|
||||
|
||||
public string LastName { get; set; } = null!;
|
||||
|
||||
public string FirstNameTranscription { get; set; } = null!;
|
||||
|
||||
public string LastNameTranscription { get; set; } = null!;
|
||||
|
||||
public string AddressLine { get; set; } = null!;
|
||||
|
||||
public string PostalCode { get; set; } = null!;
|
||||
|
||||
public string City { get; set; } = null!;
|
||||
|
||||
public string AddressCountry { get; set; } = null!;
|
||||
|
||||
public string Email { get; set; } = null!;
|
||||
|
||||
public string ContactPhone { get; set; } = null!;
|
||||
|
||||
public DateOnly BirthDate { get; set; }
|
||||
|
||||
public string DocumentNumber { get; set; } = null!;
|
||||
|
||||
public string CountryCode { get; set; } = null!;
|
||||
|
||||
public virtual Country CountryCodeNavigation { get; set; } = null!;
|
||||
|
||||
public virtual ICollection<Registration> Registrations { get; set; } = new List<Registration>();
|
||||
}
|
||||
25
DataAccess/EF_Demo/Models/Registration.cs
Normal file
25
DataAccess/EF_Demo/Models/Registration.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
// <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated>
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace EF_Demo.Models;
|
||||
|
||||
public partial class Registration
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public int PersonId { get; set; }
|
||||
|
||||
public int SportId { get; set; }
|
||||
|
||||
public int EventId { get; set; }
|
||||
|
||||
public DateTime RegisteredAt { get; set; }
|
||||
|
||||
public virtual Event Event { get; set; } = null!;
|
||||
|
||||
public virtual Person Person { get; set; } = null!;
|
||||
|
||||
public virtual Sport Sport { get; set; } = null!;
|
||||
}
|
||||
15
DataAccess/EF_Demo/Models/Sport.cs
Normal file
15
DataAccess/EF_Demo/Models/Sport.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
// <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated>
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace EF_Demo.Models;
|
||||
|
||||
public partial class Sport
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Name { get; set; } = null!;
|
||||
|
||||
public virtual ICollection<Registration> Registrations { get; set; } = new List<Registration>();
|
||||
}
|
||||
21
DataAccess/EF_Demo/Program.cs
Normal file
21
DataAccess/EF_Demo/Program.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using EF_Demo;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
Console.OutputEncoding = System.Text.Encoding.UTF8;
|
||||
|
||||
using ServiceProvider serviceProvider = DISetup.BuildDI();
|
||||
|
||||
Demo.PrintPeople(serviceProvider, 1976);
|
||||
Util.EnterToContinue();
|
||||
|
||||
int? eventId = Demo.AddEvent(serviceProvider, "Spring festival", new DateOnly(2026, 4, 30));
|
||||
Util.EnterToContinue();
|
||||
|
||||
if (eventId.HasValue)
|
||||
{
|
||||
Demo.PostponeEvent(serviceProvider, eventId.Value, days: 5);
|
||||
Util.EnterToContinue();
|
||||
|
||||
Demo.DeleteEvent(serviceProvider, eventId.Value);
|
||||
Util.EnterToContinue(clearConsole: false);
|
||||
}
|
||||
21
DataAccess/EF_Demo/Util.cs
Normal file
21
DataAccess/EF_Demo/Util.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
namespace EF_Demo;
|
||||
|
||||
public static class Util
|
||||
{
|
||||
public static void EnterToContinue(bool clearConsole = true)
|
||||
{
|
||||
Console.WriteLine("ENTER to continue");
|
||||
Console.ReadLine();
|
||||
if (clearConsole)
|
||||
{
|
||||
Console.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public static int ReadNumber()
|
||||
{
|
||||
int number;
|
||||
while (!int.TryParse(Console.ReadLine(), out number)) ;
|
||||
return number;
|
||||
}
|
||||
}
|
||||
16
DataAccess/EF_Demo/appsettings.json
Normal file
16
DataAccess/EF_Demo/appsettings.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"ConnectionStrings": {
|
||||
"EventsMssql": "Data Source=.,3030;Initial Catalog=Events;use-secrets.json-to-set-username-and-password;TrustServerCertificate=True",
|
||||
"EventsPostgres": "Host=localhost;Database=events;use-secrets.json-to-set-username-and-password;Persist Security Info=True"
|
||||
},
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Warning",
|
||||
"System": "Error",
|
||||
"Microsoft": "Error",
|
||||
"Microsoft.EntityFrameworkCore.Database.Command": "Information",
|
||||
"EF_Demo.Demo": "Information"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
70
DataAccess/EF_Demo/efpt.mssql.config.json
Normal file
70
DataAccess/EF_Demo/efpt.mssql.config.json
Normal file
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"CodeGenerationMode": 6,
|
||||
"ContextClassName": "EventsContext",
|
||||
"ContextNamespace": null,
|
||||
"FilterSchemas": false,
|
||||
"IncludeConnectionString": false,
|
||||
"IrregularWords": null,
|
||||
"MinimumProductVersion": "2.6.1465",
|
||||
"ModelNamespace": null,
|
||||
"OutputContextPath": "Data\/MSSQL",
|
||||
"OutputPath": "Models",
|
||||
"PluralRules": null,
|
||||
"PreserveCasingWithRegex": true,
|
||||
"ProjectRootNamespace": "EF_Demo",
|
||||
"Schemas": null,
|
||||
"SelectedHandlebarsLanguage": 2,
|
||||
"SelectedToBeGenerated": 0,
|
||||
"SingularRules": null,
|
||||
"T4TemplatePath": null,
|
||||
"Tables": [
|
||||
{
|
||||
"Name": "[dbo].[Country]",
|
||||
"ObjectType": 0
|
||||
},
|
||||
{
|
||||
"Name": "[dbo].[Event]",
|
||||
"ObjectType": 0
|
||||
},
|
||||
{
|
||||
"Name": "[dbo].[Person]",
|
||||
"ObjectType": 0
|
||||
},
|
||||
{
|
||||
"Name": "[dbo].[Registration]",
|
||||
"ObjectType": 0
|
||||
},
|
||||
{
|
||||
"Name": "[dbo].[Sport]",
|
||||
"ObjectType": 0
|
||||
}
|
||||
],
|
||||
"UiHint": null,
|
||||
"UncountableWords": null,
|
||||
"UseAsyncStoredProcedureCalls": true,
|
||||
"UseBoolPropertiesWithoutDefaultSql": false,
|
||||
"UseDatabaseNames": false,
|
||||
"UseDatabaseNamesForRoutines": true,
|
||||
"UseDateOnlyTimeOnly": true,
|
||||
"UseDbContextSplitting": false,
|
||||
"UseDecimalDataAnnotationForSprocResult": true,
|
||||
"UseFluentApiOnly": true,
|
||||
"UseHandleBars": false,
|
||||
"UseHierarchyId": false,
|
||||
"UseInflector": true,
|
||||
"UseInternalAccessModifiersForSprocsAndFunctions": false,
|
||||
"UseLegacyPluralizer": false,
|
||||
"UseManyToManyEntity": false,
|
||||
"UseNoDefaultConstructor": true,
|
||||
"UseNoNavigations": false,
|
||||
"UseNoObjectFilter": false,
|
||||
"UseNodaTime": false,
|
||||
"UseNullableReferences": true,
|
||||
"UsePrefixNavigationNaming": false,
|
||||
"UseSchemaFolders": false,
|
||||
"UseSchemaNamespaces": false,
|
||||
"UseSpatial": false,
|
||||
"UseT4": false,
|
||||
"UseT4Split": false,
|
||||
"UseTypedTvpParameters": true
|
||||
}
|
||||
70
DataAccess/EF_Demo/efpt.postgres.config.json
Normal file
70
DataAccess/EF_Demo/efpt.postgres.config.json
Normal file
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"CodeGenerationMode": 6,
|
||||
"ContextClassName": "EventsContext",
|
||||
"ContextNamespace": null,
|
||||
"FilterSchemas": false,
|
||||
"IncludeConnectionString": false,
|
||||
"IrregularWords": null,
|
||||
"MinimumProductVersion": "2.6.1465",
|
||||
"ModelNamespace": null,
|
||||
"OutputContextPath": "Data\/Postgres",
|
||||
"OutputPath": "Models",
|
||||
"PluralRules": null,
|
||||
"PreserveCasingWithRegex": true,
|
||||
"ProjectRootNamespace": "EF_Demo",
|
||||
"Schemas": null,
|
||||
"SelectedHandlebarsLanguage": 2,
|
||||
"SelectedToBeGenerated": 0,
|
||||
"SingularRules": null,
|
||||
"T4TemplatePath": null,
|
||||
"Tables": [
|
||||
{
|
||||
"Name": "public.country",
|
||||
"ObjectType": 0
|
||||
},
|
||||
{
|
||||
"Name": "public.event",
|
||||
"ObjectType": 0
|
||||
},
|
||||
{
|
||||
"Name": "public.person",
|
||||
"ObjectType": 0
|
||||
},
|
||||
{
|
||||
"Name": "public.registration",
|
||||
"ObjectType": 0
|
||||
},
|
||||
{
|
||||
"Name": "public.sport",
|
||||
"ObjectType": 0
|
||||
}
|
||||
],
|
||||
"UiHint": null,
|
||||
"UncountableWords": null,
|
||||
"UseAsyncStoredProcedureCalls": true,
|
||||
"UseBoolPropertiesWithoutDefaultSql": false,
|
||||
"UseDatabaseNames": false,
|
||||
"UseDatabaseNamesForRoutines": true,
|
||||
"UseDateOnlyTimeOnly": true,
|
||||
"UseDbContextSplitting": false,
|
||||
"UseDecimalDataAnnotationForSprocResult": true,
|
||||
"UseFluentApiOnly": true,
|
||||
"UseHandleBars": false,
|
||||
"UseHierarchyId": false,
|
||||
"UseInflector": true,
|
||||
"UseInternalAccessModifiersForSprocsAndFunctions": false,
|
||||
"UseLegacyPluralizer": false,
|
||||
"UseManyToManyEntity": false,
|
||||
"UseNoDefaultConstructor": true,
|
||||
"UseNoNavigations": false,
|
||||
"UseNoObjectFilter": false,
|
||||
"UseNodaTime": false,
|
||||
"UseNullableReferences": true,
|
||||
"UsePrefixNavigationNaming": false,
|
||||
"UseSchemaFolders": false,
|
||||
"UseSchemaNamespaces": false,
|
||||
"UseSpatial": false,
|
||||
"UseT4": false,
|
||||
"UseT4Split": false,
|
||||
"UseTypedTvpParameters": true
|
||||
}
|
||||
Reference in New Issue
Block a user