Test Entity Framework

This commit is contained in:
Simon Lübeß
2025-05-27 14:17:47 +02:00
parent dffd31cd0f
commit 9e7ec186cd
8 changed files with 314 additions and 0 deletions

View File

@ -0,0 +1,37 @@
using Microsoft.EntityFrameworkCore;
namespace USEntryCoach.Server.Data;
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
public BloggingContext (DbContextOptions<BloggingContext> options)
: base(options)
{
}
//public string ConnectionString { get; } = configuration.GetConnectionString("Default") ?? "No connection string";
//protected override void OnConfiguring(DbContextOptionsBuilder options) => options.UseNpgsql(ConnectionString);
}
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public List<Post> Posts { get; } = new();
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public Blog Blog { get; set; }
}

View File

@ -0,0 +1,88 @@
// <auto-generated />
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using USEntryCoach.Server.Data;
#nullable disable
namespace USEntryCoach.Server.Migrations
{
[DbContext(typeof(BloggingContext))]
[Migration("20250527114315_Initial")]
partial class Initial
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "9.0.5")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("USEntryCoach.Server.Data.Blog", b =>
{
b.Property<int>("BlogId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("BlogId"));
b.Property<string>("Url")
.IsRequired()
.HasColumnType("text");
b.HasKey("BlogId");
b.ToTable("Blogs");
});
modelBuilder.Entity("USEntryCoach.Server.Data.Post", b =>
{
b.Property<int>("PostId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("PostId"));
b.Property<int>("BlogId")
.HasColumnType("integer");
b.Property<string>("Content")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("text");
b.HasKey("PostId");
b.HasIndex("BlogId");
b.ToTable("Posts");
});
modelBuilder.Entity("USEntryCoach.Server.Data.Post", b =>
{
b.HasOne("USEntryCoach.Server.Data.Blog", "Blog")
.WithMany("Posts")
.HasForeignKey("BlogId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Blog");
});
modelBuilder.Entity("USEntryCoach.Server.Data.Blog", b =>
{
b.Navigation("Posts");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,64 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace USEntryCoach.Server.Migrations
{
/// <inheritdoc />
public partial class Initial : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Blogs",
columns: table => new
{
BlogId = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Url = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Blogs", x => x.BlogId);
});
migrationBuilder.CreateTable(
name: "Posts",
columns: table => new
{
PostId = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Title = table.Column<string>(type: "text", nullable: false),
Content = table.Column<string>(type: "text", nullable: false),
BlogId = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Posts", x => x.PostId);
table.ForeignKey(
name: "FK_Posts_Blogs_BlogId",
column: x => x.BlogId,
principalTable: "Blogs",
principalColumn: "BlogId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Posts_BlogId",
table: "Posts",
column: "BlogId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Posts");
migrationBuilder.DropTable(
name: "Blogs");
}
}
}

View File

@ -0,0 +1,85 @@
// <auto-generated />
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using USEntryCoach.Server.Data;
#nullable disable
namespace USEntryCoach.Server.Migrations
{
[DbContext(typeof(BloggingContext))]
partial class BloggingContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "9.0.5")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("USEntryCoach.Server.Data.Blog", b =>
{
b.Property<int>("BlogId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("BlogId"));
b.Property<string>("Url")
.IsRequired()
.HasColumnType("text");
b.HasKey("BlogId");
b.ToTable("Blogs");
});
modelBuilder.Entity("USEntryCoach.Server.Data.Post", b =>
{
b.Property<int>("PostId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("PostId"));
b.Property<int>("BlogId")
.HasColumnType("integer");
b.Property<string>("Content")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("text");
b.HasKey("PostId");
b.HasIndex("BlogId");
b.ToTable("Posts");
});
modelBuilder.Entity("USEntryCoach.Server.Data.Post", b =>
{
b.HasOne("USEntryCoach.Server.Data.Blog", "Blog")
.WithMany("Posts")
.HasForeignKey("BlogId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Blog");
});
modelBuilder.Entity("USEntryCoach.Server.Data.Blog", b =>
{
b.Navigation("Posts");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -3,6 +3,7 @@ using System.Text;
using System.Text.Json.Nodes; using System.Text.Json.Nodes;
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Http.HttpResults; using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using USEntryCoach.Server.Data; using USEntryCoach.Server.Data;
using USEntryCoach.Server.Services; using USEntryCoach.Server.Services;
@ -53,6 +54,9 @@ builder.Services.AddAuthorization(options =>
}); });
}); });
builder.Services.AddDbContext<BloggingContext>(options =>
options.UseNpgsql(builder.Configuration.GetConnectionString("Default")));
var app = builder.Build(); var app = builder.Build();
app.UseAuthentication(); app.UseAuthentication();
@ -176,4 +180,29 @@ app.MapGet("/ephemeral_token", async () =>
app.MapFallbackToFile("/index.html"); app.MapFallbackToFile("/index.html");
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
var context = services.GetRequiredService<BloggingContext>();
context.Database.EnsureCreated();
Blog b = new()
{
Url = "BLa"
};
Post p = new()
{
Blog = b,
Content = "sd zgsödiog söffdgkjasödfl kjasdfökljasdfölasddj föadj kfö",
Title = "Hallo Welt"
};
b.Posts.Add(p);
context.Blogs.Add(b);
context.SaveChanges();
}
app.Run(); app.Run();

View File

@ -18,7 +18,12 @@
<PackageReference Include="Microsoft.AspNetCore.SpaProxy"> <PackageReference Include="Microsoft.AspNetCore.SpaProxy">
<Version>9.*-*</Version> <Version>9.*-*</Version>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" /> <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -10,5 +10,8 @@
}, },
"Authentication": { "Authentication": {
"JwtGenerationSecret": "Please provide a GUID (without dashes) as secret." "JwtGenerationSecret": "Please provide a GUID (without dashes) as secret."
},
"ConnectionStrings": {
"Default": "User ID=us-entry-agent-dev;Password=example;Host=localhost;Port=5432;Database=us-entry-agent-dev;Pooling=true;MinPoolSize=0;MaxPoolSize=100;Connection Lifetime=0;"
} }
} }

View File

@ -12,5 +12,8 @@
"Authentication": { "Authentication": {
"JwtGenerationSecret": "Please provide a GUID (without dashes) as secret.", "JwtGenerationSecret": "Please provide a GUID (without dashes) as secret.",
"JwtExpiryTime": "00:15:00" "JwtExpiryTime": "00:15:00"
},
"ConnectionStrings": {
"Default": "[NO_CONNECTION_STRING]"
} }
} }