Home > Software engineering >  Newtonsoft.Json.JsonSerializationException: Error getting value from 'MyEntity' on 'C
Newtonsoft.Json.JsonSerializationException: Error getting value from 'MyEntity' on 'C

Time:06-01

Hi everyone, I have Asp.Net Core Web API project that is using Entity Framework Core 6.0 and Postgresql as a database

I configured my entities and their relation. Everything is fine, but there is only problem in Generic Repository Design Pattern

If I use just context.Products.ToList(), it is working perfect. But whenever I am using it with Generic Repository Design Pattern. I got an error. But there is an interesting thing. Whenever I use break point just 10 seconds or even more and I keep it up after 10 seconds, there is no error. Everything is working perfect. Is there Asynchronous problem, I never used it ?

Error enter image description here

Newtonsoft.Json.JsonSerializationException: Error getting value from 'Seats' on 'Castle.Proxies.SalonProxy'.

---> System.InvalidOperationException: An error was generated for warning 'Microsoft.EntityFrameworkCore.Infrastructure.LazyLoadOnDisposedContextWarning': An attempt was made to lazy-load navigation 'Seats.SalonProxy' after the associated DbContext was disposed. This exception can be suppressed or logged by passing event ID 'CoreEventId.LazyLoadOnDisposedContextWarning' to the 'ConfigureWarnings' method in 'DbContext.OnConfiguring' or 'AddDbContext'.

public class EfEntityRepositoryBase<TEntity, TContext> : IEntityRepository<TEntity>
where TEntity : class, IEntity, new()
where TContext : DbContext, new()
{
    public TEntity Add(TEntity entity)
    {
        using (TContext context = new TContext())
        {
            var addedEntity = context.Entry(entity);
            addedEntity.State = EntityState.Added;
            context.SaveChanges();
            return addedEntity.Entity;
        }
    }

    

    public void Delete(TEntity entity)
    {
        using (TContext context = new TContext())
        {
            var deletedEntity = context.Entry(entity);
            deletedEntity.State = EntityState.Deleted;
            context.SaveChanges();
        }
    }

    public TEntity Get(Expression<Func<TEntity, bool>> filter)
    {
        using (TContext context = new TContext())
        {
            var result = context.Set<TEntity>().SingleOrDefault(filter);
            return result;
        }
    }

    public List<TEntity> GetAll(Expression<Func<TEntity, bool>> filter = null)
    {
        using (TContext context = new TContext())
        {
    
         var result = filter == null
          ? context.Set<TEntity>().ToList()
          : context.Set<TEntity>().Where(filter).ToList();
          return result;
        }
    }
}

}

My Salon Entity

public class Salon : IEntity
{
    [Key]
    public int Id { get; set; }

    public string Name { get; set; }

    public string SalonNumber { get; set; }

    public virtual List<Seat> Seats { get; set; }

    public virtual List<Ticket> Tickets { get; set; }
}

My Seat Entity

    public class Seat : IEntity
    {
        [Key]
        public int Id { get; set; }
    
        public int SeatNumber { get; set; }
    
        public int SalonId { get; set; }
        public virtual Salon Salon { get; set; }
    }

 

MyDbContext

public class AppDbContext : DbContext
    {
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseLazyLoadingProxies().ConfigureWarnings(warnings => warnings.Ignore(CoreEventId.DetachedLazyLoadingWarning))
            .UseNpgsql("Server=localhost;Database=BiletsgoDB;Port=5432;Username=postgres;Password=123456");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Ticket>().HasOne(t => t.Category).WithMany(b => b.Tickets).HasForeignKey(t => t.CategoryId);
            modelBuilder.Entity<Ticket>().HasOne(t => t.Salon).WithMany(b => b.Tickets).HasForeignKey(t => t.SalonId);
            modelBuilder.Entity<Seat>().HasOne(t => t.Salon).WithMany(b => b.Seats).HasForeignKey(t => t.SalonId);
            modelBuilder.Entity<TicketFile>().HasOne(t => t.Ticket).WithMany(b => b.TicketFiles).HasForeignKey(t => t.TicketId);
        }

        public DbSet<Ticket> Tickets { get; set; }
        public DbSet<TicketFile> TicketFiles { get; set; }
        public DbSet<Category> Categories { get; set; }
        public DbSet<Seat> Seats { get; set; }
        public DbSet<Salon> Salons { get; set; }
    }

CodePudding user response:

I Solved the problem

params includes our entity relations

 public List<TEntity> GetAll(params Expression<Func<TEntity, object>>[] including)
    {
        using (TContext context = new TContext())
        {

            var include = context.Set<TEntity>().AsQueryable();
            including.ToList().ForEach(item =>
            {
                include = include.Include(item);
            });
            return include.ToList();
        }
    }

And I run this method from my business layer

_salonDal.GetAll(t => t.Seats,t => t.Tickets)

But I realized this way it is not efficient. Generic Repository base should use fundamentals entities. That's my opinion

  • Related