我有一个非常基本的设置来测试和理解为什么EF Core 6在向已经保存的实体的多个末端添加新项时,默认情况下不保存相关实体.
- 有人能给我解释一下这个设置出了什么问题吗?
- 我如何才能让EF默认检测到更改?有什么配置可以让EF在不手动设置
entry
状态的情况下检测更改吗?
我也遵循了Microsoft docs中提供的样本,它给了我相同的结果(DbUpdateConcurrencyException: The database operation was expected to affect 1 row(s), but actually affected 0 row(s);
)
using Microsoft.EntityFrameworkCore;
var db = new AuthorsDbContext();
db.Database.EnsureCreated();
var author = new Author();
author.Id = Guid.NewGuid();
db.Authors.Add(author);
db.SaveChanges();
// Not working
// var author1 = await db.Authors.FindAsync(new object?[] { author.Id });
// author1.Posts.Add(new Post() { Id = Guid.NewGuid(), Title = "test" });
// db.SaveChanges(); //-> DbUpdateConcurrencyException: The database operation was expected to affect 1 row(s), but actually affected 0 row(s);
// Not working
// var author1 = await db.Authors.Include(a => a.Posts).FirstAsync(a => a.Id == author.Id);
// author1.Posts.Add(new Post() { Id = Guid.NewGuid(), Title = "test" });
// db.SaveChanges(); //-> DbUpdateConcurrencyException: The database operation was expected to affect 1 row(s), but actually affected 0 row(s);
// Not working
// var author1 = await db.Authors.AsTracking().FirstAsync(a => a.Id == author.Id);
// author1.Posts.Add(new Post() { Id = Guid.NewGuid(), Title = "test" });
// db.SaveChanges(); //-> DbUpdateConcurrencyException: The database operation was expected to affect 1 row(s), but actually affected 0 row(s);
// Not working
// var author1 = await db.Authors.Include(a=>a.Posts).AsTracking().FirstAsync(a => a.Id == author.Id);
// author1.Posts.Add(new Post() { Id = Guid.NewGuid(), Title = "test" });
// db.SaveChanges(); //-> DbUpdateConcurrencyException: The database operation was expected to affect 1 row(s), but actually affected 0 row(s);
// this is the only way it works
// var author1 = await db.Authors.FindAsync(new object?[] { author.Id });
// var post = new Post() { Id = Guid.NewGuid(), Title = "test" };
// author1.Posts.Add(post);
// db.Entry(post).State = EntityState.Added;
// db.SaveChanges();
public class Author
{
public Guid Id { get; set; }
public List<Post> Posts { get; set; } = new();
}
public class Post
{
public Guid Id { get; set; }
public string Title { get; set; }
}
public class AuthorsDbContext : DbContext
{
public DbSet<Author> Authors { get; set; }
public DbSet<Post> Posts { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseMySQL("Data Source=127.0.0.1;Initial Catalog=test-db-091;User Id=root;Password=DeV12345");
}
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Author>().HasKey(a => a.Id);
builder.Entity<Post>().HasKey(a => a.Id);
builder.Entity<Author>().HasMany(a => a.Posts).WithOne(a => a.Author).HasForeignKey(a => a.AuthorId);
builder.Entity<Post>().HasOne(a => a.Author).WithMany().HasForeignKey(a => a.AuthorId);
}
}