gpt4 book ai didi

c# - Entity Framework :创建多对多关系

转载 作者:行者123 更新时间:2023-11-29 05:55:07 28 4
gpt4 key购买 nike

我们正在为应用程序使用“DB-First”方法,因为数据库在各种应用程序之间共享,所以它应该是“主”。 (MySQL)

我们有 3 个简单的表,负责 Role-To-Permission 分配,如下所示:

enter image description here

Visual-Studio 模型设计器(在从数据库构建模型之后)完美地将其重新识别为“多对多”关系,甚至没有生成“Role_to_permission”实体,因为没有进一步的属性作业)

enter image description here

到目前为止,我们在数据库中创建了这些条目,这些条目在应用程序中产生了预期的结果。 (访问映射)

目前我们正在开发一个接口(interface),允许将“权限”分配给“角色”。在这里,我有点卡住了:

  • 如果这样的关系有另一个属性(例如 requireddate),EMF 会为关系创建一个自己的实体 - 让我们假设 Permission_To_Role

然后,我可以使用以下代码“轻松地”创建一个关系:

using (MyDb db = new MyDB()){
Permission_To_Role ptr = new Permission_To_Role();
ptr.PermissionId = 5;
ptr.RoleId = 8;
ptr.CreationDate = DateTime.Now();

db.Permission_To_Role.Add(ptr);
db.SaveChanges();
}

无论如何 - 在这种情况下 - 我们在映射上没有任何附加属性,因此 EF 框架避免附加类。

我现在正在努力建立关系,但没有成功:

using (MyDB db = new MyDB())
{
//Get ids.
long permissionId = 2;
long roleID = 5;

Permission p = db.Permission.Find(permissionId);
Role r = db.Role.Find(roleID);

r.Permissions.Add(p);

db.SaveChanges();
}

这总是导致异常,我不明白为什么(ID 存在且正确)...

db.SaveChanges() 异常:

An exception of type 'System.Data.Entity.Infrastructure.DbUpdateException' occurred in EntityFramework.dll but was not handled in user code

Additional information: An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. See the InnerException for details.

内部异常:

An error occurred while updating the entries. See the inner exception for details.

内部异常:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(SELECT Permission_to_Role.PermissionId, Permission_to_Role.RoleId FROM' at line 1

想法?


更新:

SHOW CREATE TABLE Permission_to_Role;

输出:

CREATE TABLE `Permission_to_Role` (
`PermissionId` bigint(19) NOT NULL,
`RoleId` bigint(19) NOT NULL,
UNIQUE KEY `Permission_to_Role_unique` (`PermissionId`,`RoleId`),
KEY `Permission_Mapping_idx` (`PermissionId`),
KEY `Role_Mapping_idx` (`RoleId`),
CONSTRAINT `Permission_Mapping` FOREIGN KEY (`PermissionId`) REFERENCES `permission` (`Id`) ON DELETE CASCADE ON UPDATE NO ACTION,
CONSTRAINT `Role_Mapping` FOREIGN KEY (`RoleId`) REFERENCES `role` (`Id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8

更新2:

截至当前评论:我启用了 EF 生成的查询的输出,并发现了这个魅力 - 这显然是一个格式错误的查询:

INSERT INTO 
(SELECT
Permission_to_Role.PermissionId,
Permission_to_Role.RoleId
FROM
Permission_to_Role AS Permission_to_Role
)
( PermissionId, RoleId) VALUES ( 2, 1)

查询实际应该是:

INSERT INTO 
Permission_To_Role
( PermissionId, RoleId) VALUES ( 2, 1)

所以,我认为这看起来像一个“错误”?如上所述:

Whatsoever - in this case - we don't have any additional attribute on the mapping, so the additional class is avoided by the EF Framework.

没有中间 Permission_To_Role 实体,因此 EF 似乎正在尝试用查询替换此 表名

  SELECT 
Permission_to_Role.PermissionId,
Permission_to_Role.RoleId
FROM
Permission_to_Role AS Permission_to_Role

即使在插入时...(也许这适用于 MsSQL 并且对于 MySQL 连接器来说是一个糟糕的实现?)

最佳答案

我现在有点累,但终于开始工作了。

我不是 100% 肯定会概述真正的问题,因为我更改了很多东西 - 但以下“发现”是解决此问题的里程碑:

首先,

我尝试如上所述添加更多列,但没有成功。它导致映射表作为实体存在,但插入显示了同样的问题。 (插入查询,包含连线“SELECT”语句而不是表名)

其次,

我注意到,生成的映射表(在 EM-Designer 中)考虑了所有列的主键而我设计的表没有任何(复合)主键在 MySQL-Designer 中(在所有列中只设置了一个唯一的键):

enter image description here

第三,

我就像 f*** y** - 并向映射表(在数据库设计器中)添加了一个代理主键列...

enter image description here

并取消选中 EF 设计器中任何剩余列的任何主键成员身份:

enter image description here

你猜怎么着?它有效:-)

using (MyDb db = new MyDB()){
Permission_to_Role ptr = new Permission_to_Role();
ptr.PermissionId = permissionId;
ptr.RoleId = r.Id;
ptr.GrantedById = u.Id;
ptr.GrantedAt = DateTime.Now;

db.Permission_to_Role.Add(ptr);
db.SaveChanges();
}

所以,还有三件事要说:

  • 首先(我注意到这一点已经有一段时间了)- 将您的模型与数据库同步时 - 有一些更改没有被提取...您将很难弄清楚。它可能只是“索引”,但也可以是“外键约束”甚至“主键设置”之类的东西。 (将 Hibernate (Java) 视为 80/20 规则的大师:Hibernate 完成 80% - 搜索最后的 20% 由用户决定!)
  • 第二:这个问题可能是特殊数据库模式的组合,依赖第三方框架,并期望一切都自动变得干净整洁......只相信“你自己” !
  • 第三:始终为每个表使用代理主键。它一点也不有害,但避免了使用 native 主键的所有麻烦。 (无论如何您都可以将其设置为唯一键)

关于c# - Entity Framework :创建多对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50142651/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com