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);