How to set IsModified to false on a property in a related Collection in EF Core?

asp.net-core asp.net-core-1.1 c# entity-framework-core

Question

I am using Asp.Net Core 1.1 and I have two classes:

public class Scale
{
    [Key]
    public int ScaleId { get; set; }

    public string Name { get; set; }

    public string Description { get; set; }

    public decimal DefaultValue { get; set; }

    public List<ScaleLabel> Labels { get; set; }
}

public class ScaleLabel
{
    [Key]
    public int ScaleLabelId { get; set; }

    public int ScaleId { get; set; }
    public virtual Scale Scale { get; set; }

    public decimal Value { get; set; }

    public string Label { get; set; }
}

When a scale is used, all its ScaleLabels should be prohibited to update except for their Label property.

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Edit(int id, [Bind("ScaleId,Name,Description,DefaultValue,Labels")] Scale scale)
    {
        if (id != scale.ScaleId)
        {
            return NotFound();
        }

        if (ModelState.IsValid)
        {
            try
            {
                if (IsScaleUsed(id))
                {
                    _context.Scales.Attach(scale);
                    _context.Entry(scale).Collection(c => c.Labels).IsModified = false;
                }
                else
                {
                    _context.Update(scale);
                }
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!ScaleExists(scale.ScaleId))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }
            return RedirectToAction("Index");
        }
        return View(scale);
    }

If I use _context.Entry(scale).Collection(c => c.Labels).IsModified = false; then nothing is updated, and if I don't use it, then all ScaleLabels are updated. I want to specify which properties of the Scale's Labels navigation property are modified and which are not.

1
1
11/3/2018 8:11:29 PM

Accepted Answer

Rather than playing with IsModified property of the related CollectionEntry, you need to use the IsModified property of the PropertyEntry returned by Property method (or Properties property) of EntityEntry for each element of the related collection (basically the same way as you would do for specific property of any entity).

In other words, instead of

_context.Entry(scale).Collection(c => c.Labels).IsModified = false;

you would use something like this:

foreach (var label in scale.Labels)
    foreach (var p in _context.Entry(label).Properties.Where(p => p.Metadata.Name != "Label"))
        p.IsModified = false;
2
8/11/2017 4:29:07 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow