Reputation: 16713
I am building an app to help host a wine night, where guests will try to identify more expensive bottles of wine.
To keep things simple, I'll elaborate on only two entites:
public class Choice
{
public int Id { get; set; }
public virtual Event Event { get; set; }
public virtual Wine Wine { get; set; }
public virtual ApplicationUser User { get; set; }
public string Guess { get; set; }
public string Comment { get; set; }
}
public class Event
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime Date { get; set; }
public virtual ICollection<Wine> Wines { get; set; }
public virtual ICollection<Choice> Choices { get; set; }
public virtual ICollection<WineAnswer> Answers { get; set; }
}
Now, in the View where guests make a guess about which wine is the more expensive, I have hidden fields where I hold the unique identifiers for some of the other entities:
@Html.HiddenFor(event => event.Id)
Now, when a guest posts their choice via a Web API, the model is hydrated, but the model's navigation properties are anemic:
public async Task<IHttpActionResult> PostChoice(Choice choice)
{
/* At this point, the model looks like:
Choice
.Id = 0
.Guess = "A",
.Comment = "My comment!",
.Event = { Event
.Id = 1,
.Name = ""
.Date = 01/01/0001 00:00:00
}
}
So, if I attempt to perform an update on Choice
, Event
will also be updated, but with default values for its properties. Not good!
Before I save, I could do something like:
choice.Event = db.Events.Single(e => e.Id == choice.Event.Id)
But there's one db hit to get all the necessary properties for Event
, and then another one to needlessly update it with values that haven't changed. It seems like a ton of overhead.
Is there a simpler, more efficient way to do this?
Upvotes: 1
Views: 3390
Reputation: 1717
Add an EventID
property to your Choice
entity:
public class Choice
{
public int Id { get; set; }
[ForeignKey("Event")]
public int EventID { get; set; }
public virtual Event Event { get; set; }
public virtual Wine Wine { get; set; }
public virtual ApplicationUser User { get; set; }
public string Guess { get; set; }
public string Comment { get; set; }
}
This will allow you to create the one-to-many relationship between Event
and Choice
and you will not need to save the Event
navigation property when guests make a guess.
I'm not sure what you're model or view looks like, but with this approach you will simply assign the event ID from your Event
entity to the EventID
property. Then in the form you'll have a hidden input for the property:
@Html.HiddenFor(m => m.EventID)
Then simply update the Choice
entity in the database without affecting the corresponding Event
.
Upvotes: 2
Reputation: 6398
Try this while updating your model in db...
context.Entry(Choice).State = EntityState.Modified;
context.Entry(Choice).Property(x => x.Event).IsModified = false;
context.SaveChanges();
Upvotes: 0