首先使用Web API 2和EF 6.1代码。
我正在尝试添加与现有Template
和TimePeriods
有关系的新Stations
(请参阅模型)。
public class Template
{
public int TemplateID { get; set; }
public string Name { get; set; }
public List<TimePeriod> TimePeriods { get; set; }
public List<Station> Stations { get; set; }
}
public class Station
{
public int StationID { get; set; }
public string Name { get; set; }
public List<Template> Templates { get; set; }
}
public class TimePeriod
{
public int TimePeriodID { get; set; }
public TimeSpan From { get; set; }
public TimeSpan To { get; set; }
public List<Template> Templates { get; set; }
}
新模板对象包含Station
列表和TimePeriod
列表,其中包含正确的ID /主键。我希望EF能够通过查看主键来识别相关实体已经存在,但似乎没有。相反,所有相关实体都会再次添加,从而导致重复。
private SchedulingContext db = new SchedulingContext();
[ResponseType(typeof(Template))]
public IHttpActionResult PostTemplate(Template template)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Templates.Add(template);
db.SaveChanges();
return CreatedAtRoute("DefaultApi", new { id = template.TemplateID }, template);
}
这是否与我使用新的上下文有关?如果是这样,我该如何防止这种行为?
解决方案感谢Evandro:
public void PostTemplate(Template template)
{
db.Templates.Add(template);
foreach (var item in template.Stations)
{
db.Entry<Station>(item).State = EntityState.Unchanged;
}
foreach (var item in template.TimePeriods)
{
db.Entry<TimePeriod>(item).State = EntityState.Unchanged;
}
db.SaveChanges();
}
答案 0 :(得分:1)
Lorentz,这是实体框架的默认行为。您必须根据系统应该执行的操作明确定义自定义行为。
首先,您可以使用以下示例访问上下文中的实体状态:
EntityState state = db.Entry<Station>(station).State;
您可以打印状态,然后查看EF正在做什么。
现在,当您第一次收到模板的实例时,它在上下文中的状态将是已分离。
将添加到上下文后,状态将更改为已添加。这将适用于模板,工作站和TimePeriod。
即使您正确设置了Id(主键),EF也会丢弃ID,创建新ID并向表中添加新行,这就是您的程序正在发生的事情。这就是我设法在我的代码中重现的内容。
您必须为每个实体定义EntityState,以便EF知道它不应该保留新项目。以下是EF 6.1的可能值:
// This is probably what you are looking for
db.Entry<Station>(station).State = EntityState.Unchanged;
// This one maybe, if you are receiving updated values for the State
db.Entry<Station>(station).State = EntityState.Modified;
// Others that may apply for other scenarios
db.Entry<Station>(station).State = EntityState.Detached;
db.Entry<Station>(station).State = EntityState.Added;
db.Entry<Station>(station).State = EntityState.Deleted;
由于模板有多个用于Station和TimePeriod的itens,你必须迭代它们并将每一个设置为&#34; Unchanged&#34;我假设,或者&#34;修改&#34;。
让我知道它是否有效。