I got EF tracking turned off by default on my project.
I got a DB model class UserModel:
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; }
}
I want to add Owned navigation properties to be tracked before saving db context so every change in RightModel
in UserModel
will be saved to database (currently its ignoring those fields)
I want to have somewhat like this:
_dbContext.Entry(model).State = EntityState.Modified;
foreach(var navigationRightProperty in _dbContext.Entry(model).Navigations)
{
navigationRightProperty.Load();
}
Result:
Changes to RightModel will be also tracked with the main UserModel
entity.
CodePudding user response:
Model tracking is enabled by default for EF Core. So if you use the Include method on R
property while making your request and making changes to it, then you call the SaveChanges
method all changes will be saved in the database
var id = 1;
var model = _dbContext.UserModel.Include(x => x.R ).FirstOrDefalt(x => x.Id == id)
model.R.RightOne = true;
_dbContext.SaveChanges();
Also you can change your constructor for UserModel
like
public UserModel()
{
this.R = new HashSet<RightsModel>();
}
CodePudding user response:
After some time I came up to solve this issue. Drakk L solution is good if you have tracking turned on by default and want to rely on real objects.
I wanted more abstract way to achieve this:
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;
}