locked
Repository Pattern methods with ApplicationUser RRS feed

  • Question

  • User818337214 posted

    Hi,

    I have a repository pattern methods in my project.

    var jsonCartLines = JsonConvert.SerializeObject(cart.CartLines);
    var user = _unitOfWork.ApplicationUsers.GetAll().Where(i => i.UserName == userName).FirstOrDefault();
    user.CartLines = jsonCartLines;
    _unitOfWork.ApplicationUsers.Edit(user);
    _unitOfWork.SaveChanges();

    when I update user's CartLines Field, Update working also for product table. where is the logic problem ?

    namespace ECommerce.Entity
    {
        public class ApplicationUser : IdentityUser<string>
        {
            public string CartLines { get; set; }
            public ICollection<ApplicationUserRole> ApplicationUserRoles { get; set; }
        }
    }
    
    namespace ECommerce.Entity
    {
        public class ApplicationUserRole : IdentityUserRole<string>
        {
            public virtual ApplicationUser ApplicationUser { get; set; }
            public virtual ApplicationRole ApplicationRole { get; set; }
        }
    }
    namespace ECommerce.Entity
    {
        public class ApplicationRole : IdentityRole<string>
        {
            public ICollection<ApplicationUserRole> ApplicationUserRoles { get; set; }
        }
    }
    namespace ECommerce.Entity
    {
        public class Product
        {
            public string ProductCode { get; set; }
        }
    }
    namespace ECommerce.Repository.Abstract
    {
        public interface IApplicationUserRepository : IGenericRepository<ApplicationUser>
        {
        }
    }
    
    namespace ECommerce.Repository.Abstract
    {
        public interface IProductRepository : IGenericRepository<Product>
        {
        }
    }
    namespace ECommerce.Repository.Abstract
    {
        public interface IUnitOfWork : IDisposable
        {
            IApplicationUserRepository ApplicationUsers { get; }
            IProductRepository Products { get; }
            int SaveChanges();
        }
    }
    namespace ECommerce.Repository.Concrete.EntityFramework
    {
        //public class ECommerceDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string>
        public class ECommerceDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string,
                                                            ApplicationUserClaim,
                                                            ApplicationUserRole,
                                                            ApplicationUserLogin,
                                                            ApplicationRoleClaim,
                                                            ApplicationUserToken>
        {
            public ECommerceDbContext(DbContextOptions<ECommerceDbContext> options) : base(options)
            {
                Database.EnsureCreated();
            }
    
            public DbSet<Product> Products { get; set; }
            public DbSet<ApplicationUser> ApplicationUsers { get; set; }
            
            protected override void OnModelCreating(ModelBuilder modelBuilder)
            {
                base.OnModelCreating(modelBuilder);
                modelBuilder.Entity<ApplicationUser>().ToTable("ECommerceUsers");
            }
    
            public override int SaveChanges()
            {
                base.ChangeTracker.DetectChanges();
                return base.SaveChanges();
            }
        }
    }
    namespace ECommerce.Repository.Concrete.EntityFramework
    {
        public class EfApplicationUserRepository : EfGenericRepository<ApplicationUser>, IApplicationUserRepository
        {
            public EfApplicationUserRepository(ECommerceDbContext context) : base(context)
            {
            }
        }
    }
    namespace ECommerce.Repository.Concrete.EntityFramework
    {
        public class EfProductRepository : EfGenericRepository<Product>, IProductRepository
        {
            public EfProductRepository(ECommerceDbContext context) : base(context)
            {
            }
        }
    }
    namespace ECommerce.Repository.Concrete.EntityFramework
    {
        public class EfUnitOfWork : IUnitOfWork
        {
            private readonly ECommerceDbContext dbContext;
    
            public EfUnitOfWork(ECommerceDbContext _dbContext)
            {
                dbContext = _dbContext ?? throw new ArgumentNullException("dbcontext can not be null");
            }
     
            private IApplicationUserRepository _applicationUsers;
            private IProductRepository _products;
             
            public IApplicationUserRepository ApplicationUsers
            {
                get
                {
                    return _applicationUsers ?? (_applicationUsers = new EfApplicationUserRepository(dbContext));
                }
            }
        
            public IProductRepository Products
            {
                get
                {
                    return _products ?? (_products = new EfProductRepository(dbContext));
                }
            }
            
            public int SaveChanges()
            {
                try
                {
                    return dbContext.SaveChanges();
                }
                catch (Exception)
                {
                    throw;
                }
            }
             
            public void Dispose()
            {
                dbContext.Dispose();
            }
        }
    }
    public interface IGenericRepository<T> where T:class
        {
            T Get(int id);
            IQueryable<T> GetAll();
            IQueryable<T> Find(Expression<Func<T, bool>> predicate);
            void Add(T entity);
            void Delete(T entity);
            void Edit(T entity);
            void Save();
            void AddRange([NotNullAttribute] IEnumerable<T> entities);
            void DeleteRange([NotNullAttribute] IEnumerable<T> entities);
            void EditRange([NotNullAttribute] IEnumerable<T> entities);
        }



    Wednesday, September 23, 2020 5:49 PM

Answers

  • User475983607 posted

    Let's assume you wrote a perfect unit of work layer.  The functionality works exactly like Entity Framework,  What's next?  You still have to design and write the application.  You still have to create services.  What benefit does the Unit of Work pattern expose that Entity Framework does not already provide?  

    The truth is your unit of work is not well designed.  Drop the unit of work and simply use the DbContext as intended.  Simply inject the DbContext into your services and craft business logic.  You're making complex code for no valid reason.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, September 23, 2020 11:24 PM

All replies

  • User475983607 posted

    The UserManager is an API for managing accounts in Identity.  UserManager works well, it has been tested, it ready to go.   

    The repository pattern is very restrictive and will have fewer features than the UserManager.  Can you explain why you added Identity to the project if you are not going to use Identity?  Are you just using Identity for the tables?

    Wednesday, September 23, 2020 7:43 PM
  • User-474980206 posted

    as both repositories use the same dbcontext, presumable you have other code that access products. but your SaveChanges() also save for both repositories. perhaps an unexpected feature.

    I agree with above, why a generic repository that is so tightly coupled to EF?

    Wednesday, September 23, 2020 8:18 PM
  • User818337214 posted

    The UserManager is an API for managing accounts in Identity.  UserManager works well, it has been tested, it ready to go.   

    Yes,It is working very well. I use it. 

    The repository pattern is very restrictive and will have fewer features than the UserManager. 

    I use also UserManager

    thanks

    Can you explain why you added Identity to the project if you are not going to use Identity?  Are you just using Identity for the tables?

    I use also it. But the repository pattern is very easy somewhere. I also wanna learn where the problem is 

    Wednesday, September 23, 2020 9:08 PM
  • User-474980206 posted

    you don't show enough code for us to help. somewhere you are using the product repository, and because of your design, a save in one saves in both (not an intuitive design).

    Wednesday, September 23, 2020 9:12 PM
  • User818337214 posted

    you don't show enough code for us to help. somewhere you are using the product repository, and because of your design, a save in one saves in both (not an intuitive design).

    I noticed something... 

    There is  a partial view page. _cart.cshtml

    I wanted to fill the model.  so I create one static method and then I call it in _cart.cshtml

    I mean The problem occurs from usage as follows.

    _cart.cshtml

    @model WebsiteModel
    @inject IStringLocalizer<SharedResource> Localizer;
    @inject ECommerce.Repository.Abstract.IUnitOfWork unitOfWork
    @{
    
        /* test code */
        var test = unitOfWork.ApplicationUsers.GetAll().Where(i => i.UserName == User.Identity.Name).FirstOrDefault();
        test.Address = "cccccccccccc";
        unitOfWork.ApplicationUsers.Edit(test);
        unitOfWork.SaveChanges();
     
    }

    there is no problem If I use it in code behind I mean .cs

    so there is a problem for inject 

    but why ?

    Wednesday, September 23, 2020 9:52 PM
  • User475983607 posted

    Let's assume you wrote a perfect unit of work layer.  The functionality works exactly like Entity Framework,  What's next?  You still have to design and write the application.  You still have to create services.  What benefit does the Unit of Work pattern expose that Entity Framework does not already provide?  

    The truth is your unit of work is not well designed.  Drop the unit of work and simply use the DbContext as intended.  Simply inject the DbContext into your services and craft business logic.  You're making complex code for no valid reason.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, September 23, 2020 11:24 PM
  • User818337214 posted

    I found it

    services.AddScoped<IUnitOfWork, EfUnitOfWork>();

    if I use addscope  and @inject IUnitOfWork unitOfWork in view page for IUnitOfWork, this problem occurred.

    I fixed it:

    services.AddTransient<IUnitOfWork, EfUnitOfWork>();

    Thursday, September 24, 2020 12:26 PM