繁体   English   中英

实体框架:创建多对多关系

[英]Entity-Framework: Create Many-To-Many-Relations

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

我们有3个简单的表,负责角色到权限的分配,如下所示:

在此处输入图片说明

Visual-Studio模型设计器(从数据库中构建模型之后)可以很好地将其识别为“多对多”关系,甚至不会生成“ Role_to_permission” -Entity,因为分配没有其他属性)

在此处输入图片说明

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

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

  • 如果这样的关系具有另一个属性(例如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 Framework 避免了其他类。

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

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()异常:

EntityFramework.dll中发生类型为'System.Data.Entity.Infrastructure.DbUpdateException'的异常,但未在用户代码中处理

附加信息:保存不公开外键属性为其关系的实体时发生错误。 EntityEntries属性将返回null,因为无法将单个实体标识为异常的来源。 通过在实体类型中公开外键属性,可以简化保存时的异常处理。 有关详细信息,请参见InnerException。

内部异常:

更新条目时发生错误。 有关详细信息,请参见内部异常。

内部内部异常:

您的SQL语法有误; 检查对应于你的MySQL服务器版本使用附近的正确语法手册“(SELECT Permission_to_RolePermissionIdPermission_to_RoleRoleId FROM”在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

UPDATE2:

截至当前评论:我为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)

所以,我认为这看起来像个“虫子”? 正如刚才提到的:

无论如何-在这种情况下-映射上没有任何其他属性,因此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 Connector是错误的实现?)

我真的很想弄清楚这个问题的“原因”,但现在,我在该关系表中添加了另一列grantedById (引用user.id )。

在此处输入图片说明

因此,这导致在模型中生成中间实体Permission_To_Role ,并让我相信它现在可以正常工作! (原因是执行了数百次,如下所示:)

 using (MyDb db = new MyDB()){
   Permission_To_Role ptr = new Permission_To_Role();
   ptr.PermissionId = 5;
   ptr.RoleId = 8;
   ptr.GrantedById = Session.CurrentUser.Id;

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

但是,也应该只对带有2个Foreign-Key-Constraint Columns Many-To-Many-Mappings进行数据库插入,不是吗?

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

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

第一,

如上所述,我尝试添加更多列,但没有成功。 这导致Mapping-Table作为实体出现,但是插入内容显示了相同的问题。 (插入查询,包含有线的“ SELECT”语句而不是表名)

第二,

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

在此处输入图片说明

第三,

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

在此处输入图片说明

并取消选中EF-Designer中任何剩余列的主键成员资格:

在此处输入图片说明

你猜怎么着? 有用 :-)

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%取决于用户!)
  • 第二:这个问题可能是特殊的数据库模式的组合,它依赖于第三方框架,并期望所有东西都自动变得干净整洁……只相信“自己”!
  • 第三:始终为每个表使用代理主键。 它完全没有伤害,但是避免了使用本机主键的所有麻烦。 (仍然可以将其设置为唯一键)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM