public class Warehouse
{
public long Id { get; set; }
public string Name { get; set; }
public WarehousePosition Position { get; set }
}
public class WarehousePosition
{
public string Code { get; set; }
public string Description { get; set }
}
builder.OwnsOne(x => x.Position, y =>
{
y.Property(x => x.Code).IsRequired().HasColumnName("PositionCode").HasMaxLength(32);
y.Property(x => x.Description).HasColumnName("PositionDescription").HasMaxLength(64);
});
var warehouse = await repo.FindAsync(1);
warehouse.Position = new WarehousePosition();
await dbContext.SaveChangesAsync(cancellationToken);
我猜测是 new WarehousePosition()
没有进入 EF Core 的跟踪范围
var warehouse = await repo.FindAsync(1);
warehouse.Name="xxx";
warehouse.Position = new WarehousePosition();
await dbContext.SaveChangesAsync(cancellationToken);
如果这样就可以更新。Position,Name都会更新。
@风口旁的猪: 试试给 warehouse.Position.Code
赋值
@dudu:
warehouse.Position.Code="xxxx";
await dbContext.SaveChangesAsync(cancellationToken)
这样依旧是unchange状态,更新不了。
@风口旁的猪: 更新之前 warehouse.Position 的值是什么?
@风口旁的猪: 建议试试
var position = new WarehousePosition();
dbContext.Add(position);
warehouse.Position = position;
@dudu: Position 更新之前,是有值的,可以从数据库正常读取出来,正常映射。
@dudu:
var position = new WarehousePosition();
warehouse.Position = position;
dbContext.Add(position);
await dbContext.SaveChangesAsync(cancellationToken)
这样成功了。谢谢。
因为我把efcore封装了一下,完整的解决方案如下代码。
public virtual async Task<int> UpdateAsync(TEntity entity, CancellationToken cancellationToken = default)
{
//获取实体状态
var entry = DbContext.Entry(entity);
//如果实体没有被跟踪,必须指定需要更新的列,这里是防止全字段更新
if (entry.State == EntityState.Detached)
throw new ArgumentException($"实体没有被跟踪,需要指定更新的列");
//实体没有被更改
if (entry.State == EntityState.Unchanged)
{
//找出导航属性并且是值对象,我的值对象都继承了ValueObject
var navigations = entry.Navigations.Where(x => x.CurrentValue is ValueObject);
if (navigations?.Count() > 0)
{
foreach (var navigation in navigations)
{
//将值对象加入dbcontext
DbContext.Add(navigation.CurrentValue);
}
}
else
return await Task.FromResult(0);
}
return await DbContext.SaveChangesAsync(cancellationToken);
}
我试了一下,你上面的例子是可以更新的,我用的core3.1。主要代码:
DbContext的OnModelCreating方法
Main方法调用:
那试试 5.0 吧
– dudu 3年前@dudu: pomelo 5.0的版本还是alpha版本,再等等。
– 风口旁的猪 3年前