Skip to content

Commit ef3d66c

Browse files
committed
Add EF Core and post sample to remaining samples
1 parent 1db6a54 commit ef3d66c

44 files changed

Lines changed: 1051 additions & 79 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
namespace Panner.AspNetCore.Samples.FastEndpointsNet9.EFModel
2+
{
3+
using Microsoft.EntityFrameworkCore;
4+
using System;
5+
6+
public class BlogContext : DbContext
7+
{
8+
public DbSet<Post> Posts { get; set; }
9+
10+
public BlogContext() : base()
11+
{
12+
}
13+
14+
public BlogContext(DbContextOptions options) : base(options)
15+
{
16+
}
17+
18+
protected override void OnModelCreating(ModelBuilder modelBuilder)
19+
{
20+
base.OnModelCreating(modelBuilder);
21+
22+
modelBuilder.Entity<Post>()
23+
.HasData(new Post()
24+
{
25+
Id = 1,
26+
Title = Guid.NewGuid().ToString(),
27+
Content = Guid.NewGuid().ToString(),
28+
CreatedOn = DateTime.UtcNow,
29+
IsVisible = true
30+
}, new Post()
31+
{
32+
Id = 2,
33+
Title = Guid.NewGuid().ToString(),
34+
Content = Guid.NewGuid().ToString(),
35+
CreatedOn = DateTime.UtcNow,
36+
IsVisible = false
37+
}, new Post()
38+
{
39+
Id = 3,
40+
Title = Guid.NewGuid().ToString(),
41+
Content = Guid.NewGuid().ToString(),
42+
CreatedOn = DateTime.UtcNow,
43+
IsVisible = true
44+
});
45+
}
46+
}
47+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
namespace Panner.AspNetCore.Samples.FastEndpointsNet9.EFModel
2+
{
3+
using System;
4+
5+
public class Post
6+
{
7+
public int Id { get; set; }
8+
public string Title { get; set; }
9+
public string Content { get; set; }
10+
public bool IsVisible { get; set; }
11+
public int AmtLikes { get; set; }
12+
public int AmtComments { get; set; }
13+
public DateTime CreatedOn { get; set; }
14+
}
15+
}

sample/FastEndpoints/Source/FastEndpointsNet9.csproj

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,17 @@
1111
<RootNamespace>Panner.AspNetCore.Samples.FastEndpointsNet9</RootNamespace>
1212
</PropertyGroup>
1313

14-
<ItemGroup>
15-
<PackageReference Include="FastEndpoints" Version="6.0.0"/>
16-
<PackageReference Include="FastEndpoints.Generator" Version="6.0.0" PrivateAssets="all" IncludeAssets="runtime; build; native; contentfiles; analyzers; buildtransitive"/>
17-
<PackageReference Include="FastEndpoints.Security" Version="6.0.0"/>
18-
<PackageReference Include="FastEndpoints.Swagger" Version="6.0.0"/>
19-
</ItemGroup>
14+
<ItemGroup>
15+
<PackageReference Include="FastEndpoints" Version="6.0.0" />
16+
<PackageReference Include="FastEndpoints.Generator" Version="6.0.0" PrivateAssets="all" IncludeAssets="runtime; build; native; contentfiles; analyzers; buildtransitive" />
17+
<PackageReference Include="FastEndpoints.Security" Version="6.0.0" />
18+
<PackageReference Include="FastEndpoints.Swagger" Version="6.0.0" />
19+
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.6" />
20+
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="9.0.6" />
21+
</ItemGroup>
22+
23+
<ItemGroup>
24+
<ProjectReference Include="..\..\..\src\Panner.AspNetCore.csproj" />
25+
</ItemGroup>
2026

2127
</Project>
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using Microsoft.EntityFrameworkCore;
2+
using Panner.AspNetCore.Samples.FastEndpointsNet9.EFModel;
3+
using Panner.AspNetCore.Samples.FastEndpointsNet9.PannerExtensions;
4+
5+
namespace Posts;
6+
7+
sealed class Endpoint : Endpoint<Request, IEnumerable<Views.Post>>
8+
{
9+
private readonly BlogContext _context;
10+
11+
public Endpoint(BlogContext context)
12+
{
13+
_context = context;
14+
}
15+
16+
public override void Configure()
17+
{
18+
Get("/posts");
19+
AllowAnonymous();
20+
}
21+
22+
public override async Task HandleAsync(Request r, CancellationToken c)
23+
{
24+
_context.Database.EnsureCreated();
25+
var result = await _context.Posts
26+
.Apply(r.Filters ?? Array.Empty<IFilterParticle<Post>>())
27+
.Apply(r.Sorts ?? Array.Empty<ISortParticle<Post>>())
28+
.Select(x => new Views.Post
29+
{
30+
Id = x.Id,
31+
Title = x.Title,
32+
Content = x.Content,
33+
Creation = x.CreatedOn
34+
})
35+
.ToArrayAsync(c);
36+
37+
await SendAsync(result, cancellation: c);
38+
}
39+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using Microsoft.AspNetCore.Mvc;
2+
using Panner;
3+
using Panner.AspNetCore.Samples.FastEndpointsNet9.EFModel;
4+
5+
namespace Posts;
6+
7+
sealed class Request
8+
{
9+
[FromQuery]
10+
public IReadOnlyCollection<ISortParticle<Post>>? Sorts { get; set; }
11+
12+
[FromQuery]
13+
public IReadOnlyCollection<IFilterParticle<Post>>? Filters { get; set; }
14+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
namespace Panner.AspNetCore.Samples.FastEndpointsNet9.PannerExtensions
2+
{
3+
using global::Panner.AspNetCore.Samples.FastEndpointsNet9.EFModel;
4+
using global::Panner.Builders;
5+
6+
public static partial class PEntityBuilderExtensions
7+
{
8+
/// <summary>Marks the entity as sortable by popularity.</summary>
9+
public static PEntityBuilder<Post> IsSortableByPopularity(this PEntityBuilder<Post> builder)
10+
{
11+
builder.GetOrCreateGenerator<ISortParticle<Post>, SortPostsByPopularityParticleGenerator>();
12+
return builder;
13+
}
14+
}
15+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
namespace Panner.AspNetCore.Samples.FastEndpointsNet9.PannerExtensions
2+
{
3+
using global::Panner.AspNetCore.Samples.FastEndpointsNet9.EFModel;
4+
using System.Linq;
5+
6+
public class SortPostByPopularityParticle : ISortParticle<Post>
7+
{
8+
readonly bool Descending;
9+
10+
public SortPostByPopularityParticle(bool descending)
11+
{
12+
this.Descending = descending;
13+
}
14+
15+
public IOrderedQueryable<Post> ApplyTo(IOrderedQueryable<Post> source)
16+
{
17+
if (this.Descending)
18+
return source
19+
.ThenByDescending(x => x.AmtLikes)
20+
.ThenByDescending(x => x.AmtComments);
21+
else
22+
return source
23+
.ThenBy(x => x.AmtLikes)
24+
.ThenBy(x => x.AmtComments);
25+
}
26+
}
27+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using Panner.AspNetCore.Samples.FastEndpointsNet9.EFModel;
2+
3+
namespace Panner.AspNetCore.Samples.FastEndpointsNet9.PannerExtensions
4+
{
5+
public class SortPostsByPopularityParticleGenerator : ISortParticleGenerator<Post>
6+
{
7+
public bool TryGenerate(IPContext context, string input, out ISortParticle<Post> particle)
8+
{
9+
var descending = input.StartsWith('-');
10+
var remaining = descending ? input.Substring(1) : input;
11+
12+
if (!remaining.Trim().Equals("Popularity", System.StringComparison.OrdinalIgnoreCase))
13+
{
14+
particle = null;
15+
return false;
16+
}
17+
18+
particle = new SortPostByPopularityParticle(descending);
19+
return true;
20+
}
21+
}
22+
}

sample/FastEndpoints/Source/Program.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,35 @@
1+
using Microsoft.EntityFrameworkCore;
2+
using Panner.AspNetCore.Samples.FastEndpointsNet9.EFModel;
3+
using Panner.AspNetCore.Samples.FastEndpointsNet9.PannerExtensions;
4+
using Panner.Builders;
5+
16
var bld = WebApplication.CreateBuilder(args);
7+
28
bld.Services
39
.AddAuthenticationJwtBearer(s => s.SigningKey = bld.Configuration["Auth:JwtKey"])
410
.AddAuthorization()
511
.AddFastEndpoints(o => o.SourceGeneratorDiscoveredTypes = DiscoveredTypes.All)
612
.SwaggerDocument();
713

14+
bld.Services.UsePanner(c =>
15+
{
16+
c.Entity<Post>()
17+
.IsSortableByPopularity()
18+
.Property(x => x.Id, o => o
19+
.IsSortableAs(nameof(Views.Post.Id))
20+
.IsFilterableAs(nameof(Views.Post.Id))
21+
)
22+
.Property(x => x.Title, o => o
23+
.IsSortableAs(nameof(Views.Post.Title))
24+
)
25+
.Property(x => x.CreatedOn, o => o
26+
.IsSortableAs(nameof(Views.Post.Creation))
27+
.IsFilterableAs(nameof(Views.Post.Creation))
28+
);
29+
});
30+
31+
bld.Services.AddDbContext<BlogContext>(o => o.UseInMemoryDatabase("BlogDb"));
32+
833
var app = bld.Build();
934
app.UseAuthentication()
1035
.UseAuthorization()
@@ -14,4 +39,4 @@
1439
c.Errors.UseProblemDetails();
1540
})
1641
.UseSwaggerGen();
17-
app.Run();
42+
app.Run();
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace Panner.AspNetCore.Samples.FastEndpointsNet9.Views
2+
{
3+
using System;
4+
5+
public class Post
6+
{
7+
public int Id { get; set; }
8+
public string Title { get; set; }
9+
public string Content { get; set; }
10+
public DateTime Creation { get; set; }
11+
}
12+
}

0 commit comments

Comments
 (0)