Home > Blockchain >  How to create a class library that can use any Ef Core DbContext
How to create a class library that can use any Ef Core DbContext

Time:05-17

I am trying to create a class library that can consume a DbContext that will be able to query entities that have a common schema. (this is a DB first project)

I have the following in my class library project:

    public interface ITranslate
    {
        public long Id
        public long ParentId
        public long LangId
    }

In a seperate project, I would have the following:

    public partial class SectionTranslation : ITranslate
    {
         public string SectionName { get; set; }
    {

And in another project I might have the following

    public partial class TemplateTranslation : ITranslate
    {
         public string TemplateName { get; set; }
    {

What I would like to do is make the following contract a reality, however, I am not sure how to approach this one. I would want to be able to return a record that would match a common query in the GetBestTranslation method, I would want to return a SectionTranslation or TemplateTranslation Entity depending on which project is consuming the library and in the SaveTranslation method, save a translation record.

    public interface ITranslateManager
    {
        Task<T> GetBestTranslationAsync(long langId);
        Task CreateTranslationAsync<T>(long langId)
    }

Thank you all in advance for your help

CodePudding user response:

You can use a where condition on Method.

public class TranslateManager : ITranslateManager
{
    private readonly ContextDb _contextDb;

    public TranslateManager(ContextDb contextDb)
    {
        _contextDb = contextDb;
    }

    public async Task CreateTranslationAsync<T>(long langId) where T : class, ITranslate
    {
        // ToDo
    }

    public async Task<ITranslate> GetBestTranslationAsync<T>(long langId) where T : class, ITranslate
    {
        var dbSet = _contextDb.GetDbSet<T>();
        return await dbSet.Where(x => x.LangId == langId).FirstOrDefaultAsync();
    }
}

public interface ITranslate
{
    public long Id { get; set; }
    public long ParentId { get; set; }
    public long LangId { get; set; }
}

public partial class SectionTranslation : ITranslate
{
    public long Id { get; set; }
    public long ParentId { get; set; }
    public long LangId { get; set; }
    public string SectionName { get; set; }
}

public partial class TemplateTranslation : ITranslate
{
    public long Id { get; set; }
    public long ParentId { get; set; }
    public long LangId { get; set; }
    public string TemplateName { get; set; }
}

public interface ITranslateManager
{
    Task<T> GetBestTranslationAsync<T>(long langId) where T : class, ITranslate;
    Task CreateTranslationAsync<T>(long langId) where T : class, ITranslate;
}

CodePudding user response:

You can simply access your dbContext by doing this:

protected readonly PostgisDbContext Context;

protected Service(PostgisDbContext context) : base(context)
{
    Context = context;
}

Using this context is pretty easy. You can request a Dataset in your context by matching the Type passed into the generic function with an existing Dataset table Type. Don't forget to add where : T : class This will tell the function that the generic Type T is assigned by the class that you provide in the call.

public Task<T> GetAsync(long langId) where : T : class
{
    Context.Set<T>().Where(predicate).FirstOrDefault();
}

If you need the code to be more dynamic, you can add a predicate as its parameter. This will allow you to use query different queries without having to create a new function. For example x => x == true.

public Task<T> Get(Func<T, bool> predicate) => Context.Set<T>().Where(predicate).FirstOrDefault();

To call the method you have to tell the function what the generic Type is. You do this like this:

_translationService.GetAsync<MyClass>(parameter);
  • Related