Search code examples
c#mysqlentity-frameworkmariadb.net-core-3.1

EntityFramework Core with MariaDb, SaveChanges won't return Id in Production


I have a .net core 3.1 web api and I have structured it with n layered architecture. I use EntityFramwork for database operations. In my local environment I used sql server for dbcontext config and the code below worked like a charm.

namespace Core.DataAccess.EntityFramework
{
    public class EfEntityRepositoryBase<TEntity,TContext>: IEntityRepository<TEntity>
        where TEntity: class, IEntity, new()
        where TContext : DbContext,new()
    {
        public void Add(TEntity entity)
        {
            using (TContext context = new TContext())
            {
                var addedEntity = context.Entry(entity);
                addedEntity.State = EntityState.Added;
                 context.SaveChangesAsync();
            }
        }

        public async Task AddAsync(TEntity entity)
        {
            using (TContext context = new TContext())
            {
                var addedEntity = context.Entry(entity);
                addedEntity.State = EntityState.Added;
                await context.SaveChangesAsync();
            }
        }
    }
}

This is my base class for CRUD operations. And In my Manager I used this like:

public async Task<IDataResult<int>> AddGetId(GameAd gameAd)
        {
            await _gameAdDal.AddAsync(gameAd);
            return new SuccessDataResult<int>(gameAd.Id);
        }

And this was working just fine. I was getting the id value and I could return the Id value to the client for the other operations. However I had to convert Sql Server implementation to MariaDB. My production environment works with that. Now everytime I try to add something and get the Id of it, it returns 500 Error. I tried using async Task<int> AddAsync(TEntity entity) and in its body I

 public async Task<int> AddAsync(TEntity entity)
        {
            using (TContext context = new TContext())
            {
                var addedEntity = context.Entry(entity);
                addedEntity.State = EntityState.Added;
                context.SaveChanges();

                var value = addedEntity.GetDatabaseValues().GetType().GetProperty("Id").GetValue(entity, null);
                return (int)value;
            }
        }

I have spent last 3 days just to fix this but no luck. I nearly read all posts and docs related to this but I really can not figure it out. I tried returning entity parameter from base class and then returning both the entity and also the id value at the manager class but those don't work too. In short I just need to insert an entity to my MariaDB database with ef core (I used Pomelo packages in order to configure dbcontext properly. I also uninstalled Microsoft.EntityFramwork.Core as it has suggested in the docs.) Feel free to ask for further info.

ps. I also had problems with log4net, it neither log to db nor file so I removed it and now trying to add Serilog. If you ask how could I know the problem of 500 lies in this operation my answer is while a user tries to register, I check for business rules, if there is no matching username or email the register triggers and It sends an object to _userService.AddGetId(user) like this and after that there are operations where I need the Id of added user as property value. When I inspect my users table I can see the newly created user with all the correct info but other tables are just empty.


Solution

  • It was just a missing dependency. I reproduced the problem in local and realized that I forgot to inject walletService. That was why its throwing 500. The async operation returns id just fine.