I have an Address object that has a City property. When creating a brand new Address to be inserted via EF6, I fill all required basic Address properties (address line 1, postal code, etc), but I don't need a fully hydrated City instance so long as it has the ID like so:
address.City = new City { Id = 1 };
When I attempt to insert my Address, it also attempts to do validation on the City's properties, but I don't want to do any CRUD on City since all I need is its ID.
I found the below question that introduced me to detaching entries from the DbContext
so that EF does not attempt to do CRUD on said objects:
How do I stop Entity Framework from trying to save/insert child objects?
What seems to be happening when I detach the City instance is that it also nulls it out, so my Address has a null City property. This is a problem because City is also required, so a DbEntityValidationException
is thrown saying "The City field is required".
I am new to EF, so perhaps the way I am going about all of this is just wrong to begin with.
Edit By request, here's all my code:
Building my Address entity in my client before passing it to WebApi endpoint:
var user = new AppUser { Id = 1 };
var address = new Address
{
City = new City { Id = 277 },
Line1 = "123 whatever ln",
PostalCode = "01233",
CreatedBy = user,
ModifiedBy = user,
CreatedOn = DateTime.Today,
ModifiedOn = DateTime.Today
};
In my ASP.NET app, I create an array of instances I want to detach from the context:
Detached = new object[] {
value.Principle.ModifiedBy,
value.Principle.CreatedBy,
value.Principle.City
};
Just before the save, I detach all instances in the array:
foreach (var d in DetachedObjects)
{
dbContext.Entry(d).State = EntityState.Detached;
}
dbContext.SaveChanges();
What I thought was happening with detaching properties was that it was simply telling EF not to do any CRUD on them, but I didn't want it to null them out because I want the parent/principle entity to have the ID for its FK.
Here are my Address and City classes:
[DebuggerDisplay("{Line1}")]
public class Address : CisEntity
{
[MaxLength(200)]
[Required]
public string Line1 { get; set; }
[MaxLength(200)]
public string Line2 { get; set; }
[Required]
public City City { get; set; }
[MaxLength(25)]
public string PostalCode { get; set; }
}
[DebuggerDisplay("{Name}, {Province.Name}, {Province.Country.Name}")]
public class City : CisEntity, IEntityName
{
[Required]
public Province Province { get; set; }
[MaxLength(100)]
public string Name { get; set; }
}