如何使用在 Entity Framework 核心中跟踪的 [Owned] 属性获取导航属性

How to get navigation properties with [Owned] attribute Tracked in Entity Framework Core

我的项目默认关闭了 EF 跟踪。

我得到了一个数据库模型class用户模型:

public class UserModel : BaseAdminDbModel
    {
        [Key]
        public int UserId { get; set; }

        [NotMapped]
        public string UserName { get; set; }

        [Required]
        public RightsModel R { get; set; }

        public BranchUserModel()
        {
            R = new RightsModel();
        }

        [ForeignKey("UserId")]
        public UserDataModel User { get; set; }
    }

RightsModel:

[Owned]
public class RightsModel
    {
        public bool? RightOne { get; set; }
        public bool? RightTwo { get; set; }
        public bool? RightN { get; set; }
    }

我想在保存数据库上下文之前添加要跟踪的自有导航属性,因此 UserModelRightModel 中的每个更改都将保存到数据库中(目前忽略这些字段)

我想要这样的:

_dbContext.Entry(model).State = EntityState.Modified;

foreach(var navigationRightProperty in _dbContext.Entry(model).Navigations)
{
    navigationRightProperty.Load();
}

结果:

RightModel 的更改也将通过主要 UserModel 实体进行跟踪。

EF Core 默认启用模型跟踪。因此,如果您在发出请求并对其进行更改时在 R 属性 上使用 Include 方法,那么您调用 SaveChanges 方法时,所有更改都将保存在数据库中

var id = 1;
var model = _dbContext.UserModel.Include(x => x.R ).FirstOrDefalt(x => x.Id == id)

model.R.RightOne = true;

_dbContext.SaveChanges();

您也可以为 UserModel 更改构造函数,例如

public UserModel()
{
    this.R = new HashSet<RightsModel>();
}

过了一段时间我想出来解决这个问题。如果您默认打开跟踪并希望依赖真实对象,则 Drakk L 解决方案很好。

我想要更抽象的方式来实现:

var navigationOwnedProps = _dbContext
                .Entry(model)
                .Navigations
                .Where(e => e.Metadata
                    .ClrType.CustomAttributes.Any(c => c.AttributeType == 
                    typeof(OwnedAttribute))).Select(e => e.CurrentValue)
                .ToList();

foreach (var nav in navigationOwnedProps)
{
   _dbContext.Entry(nav).State = EntityState.Modified;
}