Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Entity framework 如何在.net实体框架中插入或更新多对多表_Entity Framework_Insert_Many To Many_Entity Framework 4 - Fatal编程技术网

Entity framework 如何在.net实体框架中插入或更新多对多表

Entity framework 如何在.net实体框架中插入或更新多对多表,entity-framework,insert,many-to-many,entity-framework-4,Entity Framework,Insert,Many To Many,Entity Framework 4,这看起来应该很明显,但实体框架的某些方面让我感到困惑,我无法让它工作 很简单,我有三个表,其中Id值是标识列: 用户(用户ID、用户名) 类别(categoryId、categoryName) JoinTable(UserId,CategoryId)复合 在entities designer(这是.net 4.0)中,当我导入这些表时,正如预期的那样,连接表不会出现,但用户和类别显示了一种关系。以下代码: var _context = new MyContext(); var myUser =

这看起来应该很明显,但实体框架的某些方面让我感到困惑,我无法让它工作

很简单,我有三个表,其中Id值是标识列: 用户(用户ID、用户名) 类别(categoryId、categoryName) JoinTable(UserId,CategoryId)复合

在entities designer(这是.net 4.0)中,当我导入这些表时,正如预期的那样,连接表不会出现,但用户和类别显示了一种关系。以下代码:

var _context = new MyContext();
var myUser = new User();
myUser.UserName = "joe";

var myCategory = new Category();
myCategory.CategoryName = "friends";

_context.Users.AddObject(myUser);  
myUser.Categories.Add(myCategory);

var saved = _context.SaveChanges();
返回错误(尽管未向数据库中添加任何内容):

如果在保存前添加以下内容:

_context.Categories.AddObject(myCategory);
myCategory.Users.Add(myUser);
我得到同样的错误,没有保存到数据库。如果我在尝试关联myUser和myCategory对象之前保存它们,它们都会保存,但第二次保存会引发错误,没有向联接表添加任何内容:

Cannot insert the value NULL into column 'UserId', table '...dbo.JoinTable'; column does not  allow nulls. INSERT fails. The statement has been terminated.

我显然无法理解插入了多少对多关系。我缺少什么?

我这样做的方式是首先使用实体键生成一个有效的类别实体

Category myCategory = _context.Categories.First(i => i.CategoryID == categoryIDToUse);
或者,您可以尝试将实体创建为存根,以将命中保存到DB:

Category myCategory = new Category{CategoryID = categoryIDToUse };
然后使用AttachTo方法将该实体添加到ObjectContext上的实体集(CategorySet)(您可能需要检查它是否已被附加)。然后,可以使用add方法将类别添加到用户实体中。大概是这样的:

myUser.Categories.Add(myCategory);
insert [dbo].[JoinTable]([UserId]) values (@0) select [CategoryId] from
[dbo].[JoinTable] where @@ROWCOUNT > 0 and [UserId] = @0 and [CategoryId] = scope_identity()

调用SaveChanges()。这对我很有用。

在将用户和类别实体添加到数据库后,确实需要调用SaveChanges(),然后设置它们之间的关联

然而,这里真正的问题是您列出的第二个例外。如果查看调试器中的SqlProfiler或ADO.NET profiler,您将看到在第二次SaveChanges调用期间,它看起来像这样:

myUser.Categories.Add(myCategory);
insert [dbo].[JoinTable]([UserId]) values (@0) select [CategoryId] from
[dbo].[JoinTable] where @@ROWCOUNT > 0 and [UserId] = @0 and [CategoryId] = scope_identity()
显然,如果正确编程JoinTable(两列上的复合PK),这将不起作用

如果我通过模型浏览器查看EntityModel存储,就会发现JoinTable中的CategoryId列确实将StoreGeneratedPattern设置为Identity,而将UserId设置为None。当复合PK出现时,EF为什么在生成阶段这样做,我无法理解。我将向MS发布一个与此相关的bug,但与此同时,您可以在生成后手动编辑edmx/ssdl文件,以删除标识说明符。在JoinTable的EntityType标记的属性标记下找到StoreGeneratedPattern=“Identity”字符串,并将其删除:

更改:

<Property Name="CategoryId" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />

当新的父对象添加到上下文中时,对象树中所有对象的状态都更改为“已添加”,因此EF尝试将所有此类对象保存为新记录

请参阅此链接:

您的ID属性是什么类型的?仍在努力解决这个问题。通过向联接表(DateCreated)添加虚假的第三个字段,我可以强制实体设计器显示联接表。然后我可以定义关系:var myJoin=newjointable{UserId=myUser.UserId,CategoryId=myCategory.CategoryId};并且,保存时将正确插入以下内容:_context.Categories.AddObject(myCategory);myCategory.JoinTables.Add(myJoin);myJoin.User=myUser;删除第三个字段,实体设计器将重新生成不带联接的表,我将返回“已添加具有相同键的项”错误。请检查User.UserId上的映射。看起来它可能没有被当作身份识别。是否在SSDL中设置了StoreGeneratedValue?这可能是对4.0的更改,但myUser下没有“categoryset”对象,但有“categories”:myUser.categories.Add(myCategory);但我已经在上面的代码示例中介绍了这一点。不过,我不确定您关于“使用实体键生成有效类别”部分的确切含义是什么?我使用的是EFV1.0。我更新了我的答案。“categoryset”指的是分类实体的EntitySet名称。我看到它是“Categories”,我已经更新了代码示例。我希望这能有所帮助。对,很遗憾,这就是我对上面显示的结果所做的。使用:myCategory.Users.Add(myUser)和/或myUser.Categories.Add(myCategory)返回“已添加具有相同键的项”
insert [dbo].[JoinTable]([UserId], [CategoryId]) values (@0, @1)