我正在构建一个应用程序,以帮助举办葡萄酒之夜,客人将尝试识别更昂贵的葡萄酒。
为了简单起见,我将仅阐述两个问题:
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; }
}
现在,在客人猜测哪种葡萄酒更贵的视图中,我隐藏了一些字段,其中我保留了其他一些实体的唯一标识符:
@Html.HiddenFor(event => event.Id)
现在,当客人通过Web API发布他们的选择时,模型是水合的,但模型的导航属性很贫乏:
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
}
}
因此,如果我尝试在Choice
上执行更新,Event
也会更新,但会使用其属性的默认值。不好!</ p>
在我保存之前,我可以做类似的事情:
choice.Event = db.Events.Single(e => e.Id == choice.Event.Id)
但是有一个数据库命中来获取Event
的所有必要属性,然后另一个数据库不必要地使用未更改的值更新它。这似乎是一大笔开销。
有更简单,更有效的方法吗?
答案 0 :(得分:2)
向EventID
实体添加Choice
媒体资源:
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; }
}
这样您就可以在Event
和Choice
之间创建一对多关系,并且当客人猜测时,您无需保存Event
导航属性。< / p>
我不确定您的模型或视图是什么样的,但使用此方法,您只需将Event
实体中的事件ID分配给EventID
属性即可。然后在表单中,您将拥有该属性的隐藏输入:
@Html.HiddenFor(m => m.EventID)
然后只需更新数据库中的Choice
实体,而不会影响相应的Event
。
答案 1 :(得分:0)
在db ...
中更新模型时尝试此操作context.Entry(Choice).State = EntityState.Modified;
context.Entry(Choice).Property(x => x.Event).IsModified = false;
context.SaveChanges();