TL;DR:
//Works
public async Task<Article> GetAsync(int id)
{
return (await GetAsync(entity => entity.Id.Equals(id))).SingleOrDefault();
}
//TId : struct
//Exception "Unable to create a constant value of type 'System.Object'. Only primitive types or enumeration types are supported in this context."
public async Task<TEntity> GetAsync(TId id)
{
//Same error:
//return await Set.Where(Predicate).SingleOrDefaultAsync(entity => entity.Id.Equals(id));
return (await GetAsync(entity => entity.Id.Equals(id))).SingleOrDefault();
}
Original:
When I'm using a generic method I get an exception but the same method works with non generic implementation. Why is this? Generic repository:
public class EntityRepository<TEntity, TId, TContext> : IEntityRepository<TEntity, TId>
where TEntity : class, IEntity<TId>
where TId : struct
where TContext : BaseIdentityDbContext
{
protected TContext Context { get; }
protected IDbSet<TEntity> Set { get; }
/// <summary>
/// Use to always filter entities based on a predicate
/// </summary>
protected virtual Expression<Func<TEntity, bool>> Predicate => entity => true;
protected EntityRepository(TContext context, IDbSet<TEntity> set)
{
Context = context;
Set = set;
}
/// <summary>
/// Returns the entity that corresponds to the given id
/// </summary>
/// <returns>The found entity, or null</returns>
public virtual async Task<TEntity> GetAsync(TId id)
{
return (await GetAsync(entity => entity.Id.Equals(id))).SingleOrDefault();
}
/// <summary>
/// Returns the entities that corresponds to the given predicate
/// </summary>
public virtual async Task<IReadOnlyCollection<TEntity>> GetAsync(Expression<Func<TEntity, bool>> predicate)
{
return await Set
.Where(Predicate)
.Where(predicate)
.ToListAsync();
}
}
By hiding/override the original method I can get it to work:
public class ArticleRepository : EntityRepository<Article, int, MyDbContext >, IArticleRepository
{
public ArticleRepository(MyDbContext context) : base(context, context.Articles)
{
}
public async new Task<Article> GetAsync(int id)
{
return (await GetAsync(entity => entity.Id.Equals(id))).SingleOrDefault();
}
}
I have also tried EqualityComparer but it does not work, same error for non generic implementation.
//Exception: Unable to create a constant value of type 'System.Collections.Generic.EqualityComparer`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]'. Only primitive types or enumeration types are supported in this context.
public async Task<TEntity> GetAsync(TId id)
{
return (await GetAsync(entity => EqualityComparer<TId>.Default.Equals(entity.Id, id))).SingleOrDefault();
}