I have a very simple Entity
with just 4 fields: Name, State, City and ID and some Validations.
[Table("Places")]
public class Place : BindableBase, IDataErrorInfo
{
private string name;
private string city;
private Estado state;
private int id;
[Required]
[StringLength(500)]
public string Name
{
get { return this.name; }
set { SetProperty(ref name, value); }
}
[Required]
[StringLength(500)]
public string City
{
get { return this.city; }
set { SetProperty(ref city, value); }
}
[Required]
public State State
{
get { return this.state; }
set { SetProperty(ref state, value); }
}
[Key]
public int Id
{
get { return this.id; }
set { SetProperty(ref id, value); }
}
[NotMapped]
public bool IsValid
{
get
{
return Validator.TryValidateObject(this, new ValidationContext(this), new Collection<ValidationResult>(), true);
}
}
#region IDataErrorInfo Members
/// <summary>
/// IDataErrorInfo Interface Error Message for the object.
/// </summary>
[NotMapped]
public string Error
{
get { throw new NotImplementedException(); }
}
public string this[string propertyName]
{
get
{
var context = new ValidationContext(this)
{
MemberName = propertyName
};
var results = new Collection<ValidationResult>();
bool isValid = Validator.TryValidateObject(this, context, results, true);
if (!isValid)
{
ValidationResult result = results.SingleOrDefault(p =>
p.MemberNames.Any(memberName =>
memberName == propertyName));
return result == null ? null : result.ErrorMessage;
}
return null;
}
}
#endregion
}
I can add it to the DB just fine, but once I try to update it, I get an Exception.
I am using:
public void UpdatePlace(Place place)
{
var entity = context.Places.Find(place.Id);
if (entity == null)
{
throw new InvalidOperationException("Place not found.");
}
context.Entry(place).CurrentValues.SetValues(place);
context.SaveChanges();
}
When I get to
context.Entry(place).CurrentValues.SetValues(place);
I get an Exception as:
System.InvalidOperationException
"Member 'CurrentValues' cannot be called for the entity of type 'Place' because the entity does not exist in the context. To add an entity to the context call the Add or Attach method of DbSet."
context.Entry
shows me that indeed the entity is detached
But DbSet.Find()
method's documentation shows clearly that Find()
should return an attached entity in case one is found in the DB:
Finds an entity with the given primary key values. If an entity with the given primary key values exists in the context, then it is returned immediately without making a request to the store. Otherwise, a request is made to the store for an entity with the given primary key values and this entity, if found, is attached to the context and returned. If no entity is found in the context or the store, then null is returned.
So when I try to get CurrentValues
, since the entity is detached, it throws the Exception
... but as far as I can see, there should be an attached entity, or null, not anything else....
I can't find anything about this error online, I am using SQL CE 4.0 as the DB, does anyone knows what's happening?
I think I can just Attach
the entity every time I get it from Find
but still I want to understand what's going on with my software, since this shouldn't be happening.
I think you should just change this line to:
context.Entry(entity).CurrentValues.SetValues(place);