3

In ASP.NET Core-6 Entity Framework, I am using Generic Repository:

public interface IGenericRepository<T> where T : class
{
    Task<T> GetByIdAsync(object id);
}

public class GenericRepository<T> : IGenericRepository<T> where T : class
{
    private readonly ApplicationDbContext _context;
    internal readonly DbSet<T> _table;

    public GenericRepository(ApplicationDbContext context)
    {
        _context = context;
        _table = context.Set<T>();
    }

    public virtual async Task<T> GetByIdAsync(object id)
    {
        return await _table.FindAsync(id);
    }
}

I got this warning:

'_table' is not null here Possible Null Reference Return in Generic Repository

How do I resolve this?

Thank you

2
  • 2
    Side note: Generic Repository pattern is considered a code smell nowadays: e.g. read this Commented Feb 22, 2022 at 15:11
  • Not just a smell, but an ugly antipattern that breaks EF in unrecoverable ways. A DbSet is already a generic repository. A DbContext is already a high-level multi-entity Unit-of-Work. What's the point of renaming FindAsync to GetByIdAsync ? Commented Feb 22, 2022 at 15:26

1 Answer 1

8

The answer is on another stack exchange site: https://softwareengineering.stackexchange.com/questions/433387/whats-wrong-with-returning-null

Quote

You have enabled the nullable reference types (NRT) feature of C#. This requires you to explicitly specify when a null may be returned. So change the signature to:

public TEntity? Get(Guid id)
{
    // Returns a TEntity on find, null on a miss
    return _entities.Find(id);
}

And the warning will go away.

I'm not using the feature, but expect your code should look like

public virtual async Task<T?> GetByIdAsync(object id)
{
    return await _table.FindAsync(id);
}
Sign up to request clarification or add additional context in comments.

4 Comments

Even when I made id to be long or int, I still got the same issue
@Gbenga the issue is using the antipattern "Generic Repository" in the first place. This code is simply wrong, in a lot of ways. Right now, your methods are nothing more than aliases for the DbSet<T> methods, something that' simply not needed. What do you do for inserts or updates though? If you put a SaveChanges in Insert, you break DbContext's transactional behavior. Now you have to add explicit connections and transactions. And that Insert will perform 40 DELETEs as well, because SaveChanges saves all pending modifications in a single transaction.
@PanagiotisKanavos - So what's the alternative to Generic Pattern?
@Gbenga directly using the DbSet in your code. DbSet already is a repository.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.