Can I use graphql-dotnet without Entity Framework?
I'm currently looking at this repository https://github.com/mmacneil/fullstack-jobs, and noticed that it is using EF. And everywhere I look on the internet for examples, I can only find graphql-dotnet implementations with EF.
I want to use graphql-dotnet in an existing database structure where EF is not suitable. Writing direct SQL is how I would want the application to work. Does anyone have any examples?
I don't understand how graphql-dotnet ties together with the database in the repository that I have linked
You can use GraphQL without EF. I did some investigation regarding your github link and what I've found.
First of all you should check these interfaces:
public interface IRepository<T>
{
Task<T> GetById(int id);
Task<List<T>> ListAll();
Task<T> GetSingleBySpec(ISpecification<T> spec);
Task<List<T>> List(ISpecification<T> spec);
Task<T> Add(T entity);
Task Update(T entity);
Task Delete(T entity);
}
public interface IJobRepository : IRepository<Job>
{
}
These interfaces (mostly only IRepository) define a contract how you can use your db. Next you need to check these classes: EfRepository I've omitted some implementaion details since they are not critical for understanding
public abstract class EfRepository<T> : IRepository<T> where T : class
{
protected readonly AppDbContext _appDbContext;
protected EfRepository(AppDbContext appDbContext)
{
_appDbContext = appDbContext;
}
public virtual async Task<T> GetById(int id)
{
return await _appDbContext.Set<T>().FindAsync(id);
}
public async Task<List<T>> ListAll()
{
return await _appDbContext.Set<T>().ToListAsync();
}
public async Task<T> GetSingleBySpec(ISpecification<T> spec)
{
//implementation omitted
}
public async Task<List<T>> List(ISpecification<T> spec)
{
//implementation omitted
}
public async Task<T> Add(T entity)
{
//implementation omitted
}
public async Task Update(T entity)
{
//implementation omitted
}
public async Task Delete(T entity)
{
//implementation omitted
}
}
public sealed class JobRepository : EfRepository<Job>, IJobRepository
{
public JobRepository(AppDbContext appDbContext) : base(appDbContext)
{
}
}
These classes contain implementation of the interfaces described above and EfRepository contains all code to work with db. In this case we have EF, but it is possible to use everything you want, any db or collections and etc.
So the next what we need is ContextServiceLocator (If to be more precise we need JobRepository field here)
public class ContextServiceLocator
{
public IJobRepository JobRepository => _httpContextAccessor.HttpContext.RequestServices.GetRequiredService<IJobRepository>();
public IHumanizer Humanizer => _httpContextAccessor.HttpContext.RequestServices.GetRequiredService<IHumanizer>();
private readonly IHttpContextAccessor _httpContextAccessor;
public ContextServiceLocator(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
}
And the last but not the least is FullStackJobsQuery
public class FullStackJobsQuery : ObjectGraphType
{
public FullStackJobsQuery(ContextServiceLocator contextServiceLocator)
{
FieldAsync<JobType>("job",
arguments: new QueryArguments(new QueryArgument<IntGraphType> { Name = "id" }),
resolve: async context => await contextServiceLocator.JobRepository.GetSingleBySpec(new JobSpecification(j => j.Id == context.GetArgument<int>("id", default))));
FieldAsync<ListGraphType<JobSummaryType>>("employerJobs",
resolve: async context =>
{
// Extract the user id from the name claim to fetch the target employer's jobs
var jobs = await contextServiceLocator.JobRepository.List(new JobSpecification(j => j.Employer.Id == context.GetUserId()));
return jobs.OrderByDescending(j => j.Modified);
});
FieldAsync<ListGraphType<JobSummaryType>>("publicJobs",
resolve: async context =>
{
// Fetch published Jobs from all employers
var jobs = await contextServiceLocator.JobRepository.List(new JobSpecification(j => j.Status == Status.Published));
return jobs.OrderByDescending(j => j.Modified);
});
}
}
In this class you can see how to use contextServiceLocator.JobRepository in order to resolve graphql field.