Base solution for your next web application
Open Closed

Cannot seem to add generic custom methods for repositories #1737


User avatar
0
tjackadams created

Hello,

i am trying to add a custom method into the repository base, but when i do it doesn't show as an available option in the IRepository interface. Here is the declaration

public abstract class PortalRepositoryBase<TEntity, TPrimaryKey> : EfRepositoryBase<PortalDbContext, TEntity, TPrimaryKey>
        where TEntity : class, IEntity<TPrimaryKey>
    {
        
        public ILogger Logger { get; set; }
        protected PortalRepositoryBase(IDbContextProvider<PortalDbContext> dbContextProvider)
            : base(dbContextProvider)
        {
            Logger = NullLogger.Instance;
        }

        //add common methods for all repositories
        public void Test()
        {
            
        }
    }

    public abstract class PortalRepositoryBase<TEntity> : PortalRepositoryBase<TEntity, int>
        where TEntity : class, IEntity<int>
    {
        protected PortalRepositoryBase(IDbContextProvider<PortalDbContext> dbContextProvider)
            : base(dbContextProvider)
        {

        }

        //do not add any method here, add to the class above (since this inherits it)
    }
}

and this is the implementation

public class AccountManager : AutoTaskBase, IAccountManager
    {
        private readonly IRepository<Account, long> _acountRepository;

        public AccountManager(
            IRepository<Account, long> accountRepository)
        {
            _accountRepository = accountRepository;
        }

     public voidRefreshAccountsAsync()
    {
        _accountRepository.Test();
    }

Is this the correct usage or do you have to implement a custom repository? The Test method is unavailable here . Thanks


4 Answer(s)
  • User Avatar
    0
    hikalkan created
    Support Team

    This is related to basics of C#. You did not add a method to IRepository interface, so you can not use it.

    See custom repository implementation document: <a class="postlink" href="http://www.aspnetboilerplate.com/Pages/Documents/EntityFramework-Integration#DocCustomRepositoryMethods">http://www.aspnetboilerplate.com/Pages/ ... oryMethods</a>

  • User Avatar
    0
    tjackadams created

    Hi @hikalkan,

    maybe i have misunderstood slightly.

    What my end goal is to implement an overload of InsertOrUpdate which accepts an IEnumerable as a parameter, so it does a bulk insert or update. I want to implement this for any entities that use the IRepository interface.

    Is this possible in the Framework, or would i have to implement a custom repository for each entity and duplicate the logic?

    Here is a code example of the method i am trying to implement for all repositories

    public async Task InsertOrUpdateAsync(List<TEntity> entities)
            {
                var entitiesToAdd = new List<TEntity>();
    
                
                Context.Configuration.AutoDetectChangesEnabled = false;
                foreach (var account in entities)
                {
                    entitiesToAdd.Add(account);
                    if (entitiesToAdd.Count % 500 != 0)
                    {
                        continue;
                    }
    
                    Context.Set<TEntity>().AddOrUpdate(entitiesToAdd.ToArray());
                    entitiesToAdd = new List<TEntity>();
                    Context.ChangeTracker.DetectChanges();
                    await Context.SaveChangesAsync();
                    Context.DetachAll();
                }
    
                Context.Set<TEntity>().AddOrUpdate(entitiesToAdd.ToArray());
                Context.ChangeTracker.DetectChanges();
                await Context.SaveChangesAsync();
                Context.DetachAll();
            }
    

    Many thanks

  • User Avatar
    0
    hikalkan created
    Support Team

    You can create custom repositories for your entities. To not duplicate the code, add it to the base class.

    But.. I understand you. You don't want to create classes for each entity (I would also want that). But, in C#, you can only add methods to an existing class/interface (where you don't have it's source code) by creating EXTENSION methods. You can write such an extension method, but it's not so straightforward. Because you can only reach to DbContext in EF project. You can write extension method to the EF project, Add reference from application layer to EF layer and use it. There may be other ways (using some reflection code), but it's up to your development skill :)

  • User Avatar
    0
    hikalkan created
    Support Team

    OK, I prepared it for you: <a class="postlink" href="https://gist.github.com/hikalkan/74f624c0b42c78fb1619e92b3d1972f8">https://gist.github.com/hikalkan/74f624 ... 2b3d1972f8</a>