1

I am attempting to perform an update on only fields that have changed utilising the DbContext Entry() method as discussed on StackOverflow here:

When I perform this on my Name and StartDate field everything runs perfectly, my SQL UPDATE statement includes only the Name and StartDate in the update procedure, not every field of my entity, however when I now try to update a property of a child object as well such as Company.TradingName I receive this exception:

"The property 'Company' from the property path 'Company.TradingName' is not a complex property on type 'Franchise'. Property paths must be composed of complex properties for all except the final property."

My code simply iterates through a string array of fields (new[] {"Name", "StartDate", "Company.TradingName"}) like this (where item is my franchise entity my properties belong to):

foreach (var propertyName in changedPropertyNames)
{
    _context.Entry(item).Property(propertyName).IsModified = true;
}

Any ideas? Updating complex properties should work according to the documentation as seen in the "Getting and setting the current or original values of complex properties" section of EF docs here.


Model as requested (generated by EF5):
public partial class Franchise
{
    public System.Guid Id { get; set; }
    public string Name { get; set; }
    public System.DateTime StartDate { get; set; }

    public virtual Company Company { get; set; }
}

The Company model is very simple too, just public string Name, TradingName and a few others. Nothing sinister that could interfere I wouldn't think.

Community
  • 1
  • 1
GONeale
  • 26,302
  • 21
  • 106
  • 149
  • 1
    You did not show how the Company type looks like but since the property is virtual I assume it is an Entity and not a ComplexType and this would be the reason why you get the exception because the property is not a complex property but a navigation property and you would have to get the entry for the related entity and then set the properties to modified on this entry. I am also wondering about your scenario - why you need to set specific properties as modified and not the whole entity (or nothing if the entity is modified since it will be detected). The whole entity will be sent to db anyway – Pawel Jan 10 '13 at 06:54
  • I am trying to update only specific fields on my object without first querying the object. I can query, change properties, then do a CommitChanges, but trying to setup new object, alter values with ID specified, mark as changed, then commit in hope I can run SQL UPDATE without need of SELECT first. – GONeale Jan 10 '13 at 07:07
  • `Company` is not a complex type but a regular reference. That is [an important difference](http://weblogs.asp.net/manavi/archive/2011/03/28/associations-in-ef-4-1-code-first-part-2-complex-types.aspx). – Gert Arnold Jan 10 '13 at 12:33
  • If you are setting all the properties why don't you attach the object and set it as modified? If you are not setting all properties - even if you mark only some properties as modified the whole entity will be sent to the database and I think the properties you did not set will overwrite values in the database with null/default values. – Pawel Jan 10 '13 at 16:17
  • Ok thanks for the info. Well `Company` is just my FK, I can't alter it in any way, so it looks like I can't achieve what I want to do then. I actually can't believe it, did you realise in EF5 when you fetch the object, alter it and then do a `CommitChanges` it only includes in the SQL UPDATE statement on the fields that have changed anyway? I'm sure with previous versions it included everything. Anyway, still the problem with this method is you have to perform an SQL SELECT first which I was trying to avoid. – GONeale Jan 15 '13 at 00:44

1 Answers1

1

Company appears to be not a complex property but a navigation property therefore you cannot access it using dotted property path. You need to get the entry for the related entity and then set the properties as modified accordingly.

Pawel
  • 31,342
  • 4
  • 73
  • 104