我是Entify Framework的新手,所以这可能是一个非常基本的问题。在WinForms应用程序中,我有一个数据输入页面,可以正常工作,直到我添加一个列表框并尝试使用已经做出的选择更新数据库。
在表单上,用户选择要上载的文件,并指定一个或多个可以访问该文件的部门。以下是我认为它会起作用的方式:
using (var ctx = new FCEntities())
{
var batch = new Batch() { Description = txtDescription.Text, Filename = filename, Departments = (System.Data.Objects.DataClasses.EntityCollection<Department>)lstDepartments.SelectedItems };
ctx.AddToBatches(batch);
ctx.SaveChanges();
}
但是当这不起作用时,我做了一些研究,并了解到我无法将SelectedItems强制转换为EntityCollection,因此我决定将原始集合中的项目复制到新集合中,然后使用新集合,如下所示:
using (var ctx = new FCEntities())
{
var departments = new System.Data.Objects.DataClasses.EntityCollection<Department>();
foreach (var department in lstDepartments.SelectedItems)
{
departments.Add((Department)department);
}
var batch = new Batch() {Description = txtDescription.Text, Filename = filename, Departments=departments };
ctx.AddToBatches(batch);
ctx.SaveChanges();
}
这也不起作用,并在 departments.Add 行中出现此错误:
“附加到ObjectContext的对象无法添加到 与a无关的EntityCollection或EntityReference 源对象。“
我不明白因为在我看来部门对象是否附加到ObjectContext?我显然缺少一些基本的东西,所以任何建议和/或链接到其他人如何做到这一点的例子将不胜感激。
答案 0 :(得分:1)
我想留下一个答案,以防有人在某一天遇到这个问题。 Wiktor留下的评论有助于我找到正确的方向。我觉得我缺乏基本的理解,所以我在MSDN上做了一些阅读,并且能够解决我的问题。
这背后的数据模型有三个表:Batches,Departments和Batches_Departments,它们允许批次和部门之间存在多对多的关系。
简而言之,我原始代码/逻辑的问题在于,ListBox中的Department对象与我在Save方法中使用的上下文不同。由于显而易见的原因,EF并不喜欢这样(至少现在它们是显而易见的),所以在save方法中,我使用了来自所选部门的ID来获取当前上下文中对同一部门的引用。然后我可以将此部门添加到新创建的批次中。
这里的代码现在是什么样的:
using (var ctx = new FCEntities())
{
var batch = new Batch() { Description = txtDescription.Text, Filename = filename};
foreach (var department in lstDepartments.CheckedItems)
{
var dept = (from d in ctx.Departments where d.DepartmentID == ((Department)department).DepartmentID select d).First();
batch.Departments.Add(dept);
}
ctx.Batches.AddObject(batch);
ctx.SaveChanges();
}
希望这有助于处理同一问题的其他人。