I have Generic Repository below. I also have Entity framework class called Queue which maps to database. The goal is use implement the repository in API for QueueTable.
Base Repository:
public class BaseRepository<T, TPrimaryKey> : IRepository<T, TPrimaryKey> where T : class, IEntity<TPrimaryKey>
{
protected readonly DbContext _context;
protected virtual DbSet<T> Table { get; }
protected IQueryable<T> All => Table.AsNoTracking();
public BaseRepository(DbContext context)
{
_context = context;
Table = _context.Set<T>();
}
public IQueryable<T> GetAll()
{
return All;
}
public async Task DeleteAsync(T entity)
{
await Task.FromResult(_context.Set<T>().Remove(entity));
}
Generic Repository:
public interface IRepository<T, TPrimaryKey> where T : IEntity<TPrimaryKey>
{
IQueryable<T> GetAll();
DeleteAsync(T entity);
............
Model
public class Queue
{
public Queue()
{
QueueHistory = new HashSet<QueueHistory>();
}
public int QueueId { get; set; }
public int? QueueStatusId { get; set; }
public int? OriginalDepartmentId { get; set; }
public int? CreatedByUserId { get; set; }
public int? ObjectType { get; set; }
public int? ObjectId { get; set; }
IEntity:
public interface IEntity<TPrimaryKey>
{
[NotMapped]
TPrimaryKey Id { get; set; }
}
public interface IEntity : IEntity<int>
{
}
API:
In trying to declare the Repository in API Controller, it states this
public class QueuesController : ControllerBase
{
private readonly AssessmentContext _context;
public Queue queue = new Queue();
public BaseRepository<Queue,QueueId> queueRepository;
Error:
The type .Entities.Queue' cannot be used as type parameter 'T' in the generic type or method 'BaseRepository<T, TPrimaryKey>'. There is no implicit reference conversion from 'DomainModels.Entities.Queue' to 'Interfaces.IEntity<QueueId>'.
Trying to convert creates issue.
How would I resolve this error?
I think the issue you are having is understanding how type constraints work, a rough skeleton (that makes the compiler happy) of what you are looking for is something like this, I leave the actual implementation to you :)
Note that I remade some of the classes/interfaces, you can use the IEntity you have yourself from EF, eg:
public interface IEntity<T>
{
T Id {get;set;}
}
public interface IRepository<T, TPrimaryKey> where T: IEntity<TPrimaryKey>{}
public class BaseRepository<T, TPrimaryKey> : IRepository<T, TPrimaryKey> where T: class, IEntity<TPrimaryKey>{}
public class Queue : IEntity<int>
{
public int Id {get;set;}
}
public class QueueRepository : BaseRepository<Queue, int>
{
}
public class QueueController
{
//Not a good idea
private readonly BaseRepository<Queue, int> queueRepository;
//Better
private readonly QueueRepository _queueRepository;
}