我本周试图与EF交手,到目前为止我还好,但我刚刚遇到了我的第一个主要障碍。我有一个项目表和一个类别表。每个项目都可以使用多个类别进行“标记”,因此我创建了一个链接表。两列,一列是项目的主要ID,另一列是类别的主要ID。我手动向数据库添加了一些数据,我可以在代码中通过EF查询它。
现在我想用一个现有类别“标记”一个新项目。我有要添加的类别ID和项目的ID。我使用linq将它们作为实体加载,然后尝试以下操作。
int categoryToAddId = Convert.ToInt32(ddlCategoriesRemaining.SelectedValue);
var categoryToAdd = db.CollectionCategorySet.First(x => x.ID == categoryToAddId);
currentCollectionItem.Categories.Add(categoryToAdd);
db.SaveChanges();
但是我得到“无法更新EntitySet'collectionItemCategories',因为它有一个DefiningQuery,并且元素中不存在支持当前操作的元素。”
我错过了什么吗?这不是正确的方法吗?我尝试移除相同的东西,也没有运气。
答案 0 :(得分:1)
我想我已经设法自己回答了这个问题。经过大量挖掘后发现实体框架(因为它来自VS2008 SP1)实际上并不能很好地支持多对多的关系。框架确实通过关系创建了来自另一个对象的对象列表,这非常好,但是当涉及添加和删除关系时,这不可能非常容易地完成。您需要编写自己的存储过程来执行此操作,然后使用Function Import路径将它们注册到Entity Framework。
此路由还存在另一个问题,即不返回任何内容的函数导入(如添加多对多关系)不会添加到对象上下文中。所以当你编写代码时,你不能像你期望的那样使用它们。
现在我将简单地使用executenonquery()以旧式方式执行这些过程。显然对此的更好支持应该会在VS2010中出现。
如果有人觉得我的事实有问题,请随意我。
答案 1 :(得分:0)
创建Item对象后,需要将Item对象设置为Item的Categories属性上的Category对象。如果要添加新的Item对象,请执行以下操作:
Using (YourContext ctx = new YourContext())
{
//Create new Item object
Item oItem = new Item();
//Generate new Guid for Item object (sample)
oItem.ID = new Guid();
//Assign a new Title for Item object (sample)
oItem.Title = "Some Title";
//Get the CategoryID to apply to the new Item from a DropDownList
int categoryToAddId = Convert.ToInt32(ddlCategoriesRemaining.SelectedValue);
//Instantiate a Category object where Category equals categoryToAddId
var oCategory = db.CategorySet.First(x => x.ID == categoryToAddId);
//Set Item object's Categories property to the Category object
oItem.Categories = oCategory;
//Add new Item object to db context for saving
ctx.AddtoItemSet(oItem);
//Save to Database
ctx.SaveChanges();
}
答案 2 :(得分:0)
您是否已将链接表中的两列上的外键放到项目和类别中,或者在映射详细信息中将关系定义为多对多?