Skip to content

Instantly share code, notes, and snippets.

@stevefan1999-personal
Created July 26, 2025 04:07
Show Gist options
  • Save stevefan1999-personal/a441167630818631d9ede138fd9ef11b to your computer and use it in GitHub Desktop.
Save stevefan1999-personal/a441167630818631d9ede138fd9ef11b to your computer and use it in GitHub Desktop.
Hot Chocolate + FreeSQL
#!/usr/bin/dotnet run
#:sdk Microsoft.NET.Sdk.Web
#:package HotChocolate.AspNetCore@*
#:package FreeSql@*
#:package FreeSql.Provider.Sqlite@*
#:package FreeSql.Extensions.Linq@*
#:package FreeSql.DbContext@*
#:property TrimMode=partial
using FreeSql;
using FreeSql.DataAnnotations;
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddSingleton(r => new FreeSql.FreeSqlBuilder()
.UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=freedb.db")
.UseMonitorCommand(cmd => Console.WriteLine($"Sql:{cmd.CommandText}"))
.UseAutoSyncStructure(true)
.Build().SetDbContextOptions(opt => { opt.EnableCascadeSave = true; }))
.AddFreeRepository();
builder.Services.AddGraphQLServer()
.AddGlobalObjectIdentification()
.AddQueryType<Query>()
.AddMutationType<Mutation>()
.AddQueryFieldToMutationPayloads()
.ModifyRequestOptions(o => o.IncludeExceptionDetails = true);
var app = builder.Build();
app.MapGraphQL();
app.Run();
[Node(IdField = nameof(Name))]
public record Author
{
[ID]
[Column(IsIdentity = true, IsPrimary = true)] public required string Name { get; init; }
[Navigate(nameof(Book.AuthorName))]
public IList<Book>? Books { get; set; }
public static async Task<Author> Get(string name, IBaseRepository<Author> service)
{
return await service.Select.Where(x => x.Name == name).FirstAsync();
}
};
[Node(IdField = nameof(Title))]
public record Book
{
[ID]
[Column(IsIdentity = true, IsPrimary = true)] public required string Title { get; init; }
public string AuthorName { get; set; }
[Navigate(nameof(AuthorName))]
public Author? Author { get; set; }
public static async Task<Book> Get(string title, IBaseRepository<Book> service)
{
return await service.Select.Where(x => x.Title == title).FirstAsync();
}
};
public class Query
{
public IQueryable<Book> GetBook(IBaseRepository<Book> books)
=> books.Select.Include(x => x.Author).AsQueryable();
}
public class Mutation
{
public Task<Author> AddAuthor(string author, IBaseRepository<Author> authors)
=> authors.InsertAsync(new Author { Name = author });
public Task<Book> AddBook(string title, string author, IBaseRepository<Book> books, IBaseRepository<Author> authors)
=> books.InsertOrUpdateAsync(new Book { Title = title, AuthorName = author });
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment