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:
Boris Milašinović
2026-04-19 16:49:07 +02:00
parent 44a663e170
commit 6f56d107a2
89 changed files with 7305 additions and 0 deletions

View File

@@ -0,0 +1,60 @@
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text.RegularExpressions;
namespace Logging;
public class DataLoader : IDataLoader
{
private readonly ILogger<DataLoader> logger;
public DataLoader(ILogger<DataLoader> logger)
{
this.logger = logger;
}
public List<(string, DateOnly)> LoadData(string filename)
{
List<(string, DateOnly)> list = new();
if (!File.Exists(filename))
{
string message = $"File {filename} does not exist";
logger.LogError(message);
throw new FileNotFoundException(message);
}
else
{
//use File.ReadAllLines for small files
using (var reader = new StreamReader(File.OpenRead(filename)))
{
string? line;
while((line = reader.ReadLine()) != null) {
string pattern = "[0-3]?[0-9].[0-3]?[0-9].[0-9]{4}.";
var match = Regex.Match(line, pattern);
if (match.Success)
{
string datetext = line.Substring(match.Index, match.Length);
if (DateOnly.TryParseExact(datetext, "d.M.yyyy.", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateOnly date))
{
var item = (line.Remove(match.Index, match.Length).Trim(), date);
logger.LogTrace(item.ToString());
list.Add(item);
}
else
{
logger.LogWarning("Invalid date in line: " + line);
}
}
else
{
logger.LogWarning("No date found in line: " + line);
}
}
}
}
return list;
}
}

View File

@@ -0,0 +1,9 @@
using System;
using System.Collections.Generic;
namespace Logging;
public interface IDataLoader
{
List<(string, DateOnly)> LoadData(string filename);
}

View File

@@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.6" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.6" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.6" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="10.0.6" />
<PackageReference Include="NLog" Version="6.1.2" />
<PackageReference Include="NLog.Extensions.Logging" Version="6.1.2" />
</ItemGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="data.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="nlog.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,45 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
using System;
using System.Linq;
namespace Logging;
class Program
{
static void Main(string[] args)
{
using (var serviceProvider = BuildDI())
{
var dataLoader = serviceProvider.GetRequiredService<IDataLoader>();
var list = dataLoader.LoadData("data.txt");
var sortQuery = list.OrderByDescending(t => t.Item2)
.ThenBy(t => t.Item1);
Console.WriteLine("Valid data: ");
foreach (var item in sortQuery)
{
Console.WriteLine($"{item.Item2:yyyy-MM-dd} {item.Item1}");
}
}
}
private static ServiceProvider BuildDI()
{
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
IServiceCollection services = new ServiceCollection();
var provider = services.AddLogging(configure => {
configure.AddConfiguration(configuration.GetSection("Logging"));
configure.AddConsole();
configure.AddNLog(new NLogProviderOptions { RemoveLoggerFactoryFilter = false });
})
.AddTransient<IDataLoader, DataLoader>()
.BuildServiceProvider();
return provider;
}
}

View File

@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Trace",
"System": "Warning",
"Microsoft": "Trace"
}
}
}

View File

@@ -0,0 +1,5 @@
Ana 22.5.1988.
01.03.1995. Ivan John
Ema
Mario 15.13.1980.
Klara 11.07.1998.

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogLevel="Warn"
internalLogFile="logs/internal-nlog.txt">
<!-- the targets to write to -->
<targets>
<!-- write logs to file -->
<target xsi:type="File" name="allfile" fileName="logs/nlog-all-${shortdate}.log"
layout="${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}|${logger}|${uppercase:${level}}|${message} ${exception}" />
<!-- another file log, only own logs. Uses some ASP.NET core renderers -->
<target xsi:type="File" name="ownFile" fileName="logs/nlog-own-${shortdate}.log"
layout="${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}|${logger}|${uppercase:${level}}| ${message} ${exception}" />
<!-- write to the void aka just remove -->
<target xsi:type="Null" name="blackhole" />
</targets>
<!-- rules to map from logger name to target -->
<rules>
<!--All logs, including from Microsoft-->
<logger name="*" minlevel="Trace" writeTo="allfile" />
<!--Skip Microsoft logs and so log only own logs-->
<logger name="Microsoft.*" minlevel="Trace" writeTo="blackhole" final="true" />
<logger name="*" minlevel="Information" writeTo="ownFile" />
</rules>
</nlog>