I have the following classes (reduced for simplicity).
public class User : Entity
{
public List<Skill> Skills { get; set; }
}
public class Skill : ValueObject
{
public string Name { get; private set; }
}
My UserConfiguration class is the following:
public class UserConfiguration : IEntityTypeConfiguration<User>
{
public void Configure(EntityTypeBuilder<User> builder)
{
builder
.OwnsMany(user => user.Skills);
}
}
Here I am saying EF that my User class owns some Skills and it generates the following table:

I use the Unit of Work pattern, so in my repository I do the following on my Update method:
public virtual void Update(T entityToUpdate)
{
_context.Entry(entityToUpdate).State = EntityState.Modified;
}
And after updating I call my Commit method, which saves the changes:
public void Commit()
{
_dbContext.SaveChanges();
}
As far as I have been able to see, on getting the User entity I am receiving all the properties correctly (including the Skills), but on updating is updating each property but the Skills.
I have tried to manually set the Skill's table Primary Key and Foreign Key changing the UserConfiguration class this way (with the same result, skills are not updated):
public class UserConfiguration : IEntityTypeConfiguration<User>
{
public void Configure(EntityTypeBuilder<User> builder)
{
builder
.OwnsMany(user => user.Skills, skill =>
{
skill.WithOwner().HasForeignKey("UserId");
skill.Property<int>("Id");
skill.HasKey("id");
});
}
}
I have also tried to change my Update method to:
public virtual void Update(T entityToUpdate)
{
_dbSet.Update(entityToUpdate);
}
But I am getting the following exception: Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException : Database operation expected to affect 1 row(s) but actually affected 0 row(s).
Note that Skill is a ValueObject (it has a shadow Id). I actually believe there should be the problem.
Thanks a lot for your help.
Edit: Since @pejman answer is not working for me I am going to put here my UnitOfWork, Repository and Context (reduced for simplicity), since are the only things I have not done like @pejman, maybe the problem is right there, but I am not able to see it.
Repository:
class BaseRepository<T> : IRepository<T> where T : Entity
{
private readonly Context _context;
private readonly DbSet<T> _dbSet;
public BaseRepository(Context context)
{
_context = context;
_dbSet = context.Set<T>();
}
public virtual T GetById(Guid id) => _dbSet.AsNoTracking().FirstOrDefault(x => x.Id == id);
public virtual void Update(T entityToUpdate)
{
_context.Entry(entityToUpdate).State = EntityState.Modified;
}
}
Unit of work:
public class UnitOfWork : IUnitOfWork
{
private const int SqlObjectAlreadyExistsErrorNumber = 2627;
private readonly Context _dbContext;
private BaseRepository<User> _users;
public UnitOfWork(Context dbContext)
{
_dbContext = dbContext;
}
public IRepository<User> Users
{
get
{
return _users ??= new BaseRepository<User>(_dbContext);
}
}
public void Commit()
{
_dbContext.SaveChanges();
}
}
Context:
public class Context : DbContext
{
public Context(DbContextOptions<DeribeContext> options)
: base(options)
{
}
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfigurationsFromAssembly(typeof(DeribeContext).Assembly);
base.OnModelCreating(modelBuilder);
}
}