【发布时间】:2015-05-17 17:58:09
【问题描述】:
我有一个使用代码优先实体框架模型创建的一对多父子关系。
下面的代码创建一个引用现有父项的新子项的结果是我最终得到了一个新的父项。
我已经看到一个建议的解决方案是将父级附加到上下文或更改它的 EntityState。但是我认为这不起作用,因为这两种模型存在于不同的环境中。
在我看来,不同的上下文总是很奇怪,但我在某处读到,这样做是很常见的,以使每个模型都保持模块化。 (即使他们使用相同的连接字符串等)
所以问题是: 我如何确保 Child 与现有的父级关联,而不是与新创建的父级关联?
即使不同的 dbContexts 没有导致问题,这样做是否明智?
我的控制器代码:
[HttpPost]
[ValidateAntiForgeryToken]
[ValidateInput(false)]
public ActionResult Create([Bind(Include = "Information_Id,Information_Title,Information_LinkText,Information_URLBody")] Information information, int InformationContainer_Id)
{
InformationContainerDBContext dbContainer = new InformationContainerDBContext();
//information.Information_Container = (from p in dbContainer.InformationContainers where p.InformationContainer_Id == InformationContainer_Id select p).ToList()[0];
information.Information_Container = dbContainer.InformationContainers.Single(o => o.InformationContainer_Id == InformationContainer_Id);
if (ModelState.IsValid)
{
dbContainer.Entry(information.Information_Container).State = EntityState.Unchanged;
db.Informations.Add(information);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(information);
}
我的模特:
家长:
public class InformationContainer
{
[Key]
public int InformationContainer_Id { get; set; }
[Required]
public string InformationContainer_Title { get; set; }
[InverseProperty("Information_Container")]
public List<Information> Informations{ get; set; }
}
public class InformationContainerDBContext : DbContext
{
public InformationContainerDBContext()
: base(ConfigurationManager.ConnectionStrings["DataDBString"].ConnectionString)
{
}
public DbSet<InformationContainer> InformationContainers { get; set; }
}
孩子:
public class Information
{
[Key]
public int Information_Id { get; set; }
[Required]
public string Information_Title { get; set; }
[Required]
public string Information_LinkText { get; set; }
[Required]
[AllowHtml]
public string Information_URLBody { get; set; }
public InformationContainer Information_Container { get; set; }
}
public class InformationDBContext : DbContext
{
public InformationDBContext()
: base(ConfigurationManager.ConnectionStrings["DataDBString"].ConnectionString)
{
}
public DbSet<Information> Informations { get; set; }
}
我的观点:
@model eCommSite.Areas.Admin.Models.Information
@{
ViewBag.Title = "Information Pages - Create";
}
<script type="text/javascript" src="~/Scripts/tinymce/tinymce.min.js"></script>
<script>tinymce.init({ selector: 'textarea' });</script>
<h2>Information Pages</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Create</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.Information_Title, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Information_Title, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Information_Title, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Information_LinkText, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Information_LinkText, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Information_LinkText, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Information_Container, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
<select name="InformationContainer_Id">
<option value="1">Help</option>
<option value="2">Company</option>
<option value="3">Information For Parents</option>
</select>
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Information_URLBody, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10" style=" height:500px!important; width: 80%;">
<textarea id=" wysiwyg"
style=" height:350px; width: 500px;"
name="Information_URLBody"></textarea>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
【问题讨论】:
-
尝试删除
dbContainer.Entry(information.Information_Container).State = EntityState.Unchanged;information.Information_Container如果您向其中添加新信息条目,则应该处于已更改状态。 -
我认为这些多重背景造成的弊大于利。事实上,我看不到让多个上下文指向同一个数据库有什么帮助。如果有人有任何线索,请赐教。我真的很想知道。
-
@rraszewski 这是一个解决方案的尝试,可以忽略它,结果是一样的
-
MCVE,拜托...这里发生了很多事情。
标签: c# entity-framework model-view-controller one-to-many dbcontext