I have an error: Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: 'The database operation was expected to affect 1 row(s), but actually affected 0 row(s); data may have been modified or deleted since entities were loaded.
when I am trying to add a comment to a post in database using Entity Framework and save changes. I don't know why. What am I doing wrong?
Here I have the error:
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
private readonly ApplicationDbContext _applicationDbContext;
public ValuesController(ApplicationDbContext applicationDbContext)
{
_applicationDbContext = applicationDbContext;
}
[HttpGet]
public IActionResult Get()
{
var post = _applicationDbContext.Posts.First();
post.AddComment(Guid.NewGuid(), "aaa", "bbb");
_applicationDbContext.SaveChanges(); // here error
return Ok();
}
}
Entity Framework configuration - probably something is wrong here?:
public class PostConfiguration : IEntityTypeConfiguration<Post>
{
public void Configure(EntityTypeBuilder<Post> builder)
{
builder.ToTable("Posts");
builder.HasKey(x => x.PostId);
builder.HasMany(x => x.Comments).WithOne().HasForeignKey("PostId");
}
}
public class CommentConfiguration : IEntityTypeConfiguration<Comment>
{
public void Configure(EntityTypeBuilder<Comment> builder)
{
builder.ToTable("Comments");
builder.HasKey(x => x.CommentId);
builder.Property(x => x.CommentStatus)
.HasColumnName("CommentStatusId")
.HasConversion(new EnumToNumberConverter<CommentStatus, int>());
}
}
public class ApplicationDbContext : DbContext
{
public DbSet<Post> Posts { get; set; }
public DbSet<Comment> Comments { get; set; }
public ApplicationDbContext(
DbContextOptions options) : base(options)
{
}
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken())
{
var result = await base.SaveChangesAsync(cancellationToken);
return result;
}
protected override void OnModelCreating(ModelBuilder builder)
{
builder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
base.OnModelCreating(builder);
}
}
Here is my Post class:
public class Post
{
public Guid PostId { get; private set; }
public string Title { get; private set; }
public string Content { get; private set; }
public List<Comment> Comments { get; private set; } = new List<Comment>();
public Post(Guid postId, string title, string content)
{
PostId = postId;
Title = title;
Content = content;
}
public void AddComment(Guid commentId, string author, string content)
{
var comment = new Comment(commentId, author, content);
Comments.Add(comment);
}
}
Here is my Comment class:
public class Comment
{
public Guid CommentId { get; private set; }
public string Author { get; private set; }
public string Content { get; private set; }
public CommentStatus CommentStatus { get; private set; }
public Comment(Guid commentId, string author, string content)
{
CommentId = commentId;
Author = author;
Content = content;
CommentStatus = CommentStatus.New;
}
}
Here is my CommentStatus class:
public enum CommentStatus
{
New = 1,
Accepted = 2,
Rejected = 3
}
In Program.cs I have:
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(connectionString));