0

I have the following entities: PushTemplate and PushTemplateMessage. One PushTemplate can have many PushTemplateMessages. I have repositories for this. All works for the create operation. But problem starts when I try to update PushTemplate and set new text for messages. Insetad of an update I see new one PushTemplateMessage. I'll show my code.

Entity PushTemplate:

public class PushTemplate
{
    public int PushTemplateId { get; set; }

    [Required]
    public List<PushTemplateMessage> Messages { get; set; }

    public DateTime CreatedAt { get; set; }

    public PushTemplate()
    {
        CreatedAt = DateTime.UtcNow;
    }
}  

Entity PushTemplateMessage:

public class PushTemplateMessage
{
    public int PushTemplateMessageId { get; set; }

    public string PushTitle { get; set; }
    public string PushMessage { get; set; }
    public PushTemplate PushTemplate { get; set; }
}

Repository PushTemplateRepository:

public class PushTemplateRepository : IPushTemplateRepository
{
    private readonly ApplicationDbContext _applicationContext;

    public PushTemplateRepository(ApplicationDbContext applicationContext)
    {
        _applicationContext = applicationContext;
    }

    public IQueryable<PushTemplate> PushTemplates => _applicationContext.PushTemplates;

    public void Save(PushTemplate pushTemplate)
    {
        if (pushTemplate.PushTemplateId == 0)
        {
            _applicationContext.PushTemplates.Add(pushTemplate);
        }
        else
        {
            PushTemplate dbEntity = _applicationContext.PushTemplates.Find(pushTemplate.PushTemplateId);

            dbEntity.Messages = new List<PushTemplateMessage>();

            _applicationContext.SaveChanges();

            dbEntity.Messages = pushTemplate.Messages;

        }

        _applicationContext.SaveChanges();
    }
}

Database context:

public class ApplicationDbContext : IdentityDbContext
{
    private readonly string _connectionString;

    public DbSet<PushTemplate> PushTemplates { get; set; }
    public DbSet<PushTemplateMessage> TemplateMessages { get; set; }
    public ApplicationDbContext(IConfiguration configuration)
    {
        _connectionString = configuration.GetConnectionString("MakeAppDb");
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseNpgsql(_connectionString, b => b.MigrationsAssembly("MakeAppPushesNet_2"));
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<PushTemplate>()
            .HasMany(x => x.Messages)
            .WithOne(y => y.PushTemplate)
            .OnDelete(DeleteBehavior.Cascade);
    }
}

And finally call to update operation from my controller:

PushTemplate pushTemplate = new PushTemplate
{
        Messages = pushTemplateMessages // new list of messages
}; 

_pushTemplateRepository.Save(pushTemplate);

After this operation I have the old PushTemplateMessage and new version of PushTemplateMessage. But I need only new one! As you can see, in the repository I have tried to 'clean' old PushTemplateMessages to set then new list. But it continues to merge old data with new! Where is the mistake?

Aleksej_Shherbak
  • 2,757
  • 5
  • 34
  • 71

1 Answers1

0

Ok, I have solved it. This post was helpful. This is from the answer.

So, if you want to synchronize (not add), even if you want set new values as NULL you have to use include("EntityName") on your db context. Now my save/update repository code is:

    public void Save(PushTemplate pushTemplate)
    {
        if (pushTemplate.PushTemplateId == 0)
        {
            _applicationContext.PushTemplates.Add(pushTemplate);
        }
        else
        {
            PushTemplate dbEntity = _applicationContext.PushTemplates
                .Include(x => x.Messages)
                .FirstOrDefault(x => x.PushTemplateId == pushTemplate.PushTemplateId);

            dbEntity.Messages = pushTemplate.Messages;

        }

        _applicationContext.SaveChanges();
        }

As you can see I just use Include(). And now I can set null or synchronize it with a new list of values.

Aleksej_Shherbak
  • 2,757
  • 5
  • 34
  • 71