We are using the "DB-First" approach for an application, cause the Database is shared between various applications, so it should be the "master". (MySQL)
We have 3 simple tables, responsible for the Role-To-Permission Assignment, like this:
The Visual-Studio Model Designer (after building the model from the database) perfectly fine recocnices this as a "Many-To-Many" relation, not even generating a "Role_to_permission"-Entity, as there are no further attributes on the assignment)
Until now, we created those entries in the database, which lead to the expected outcome within the application. (Accessing mappings)
Currently we are working on an Interface, allowing to assign "Permissions" to "Roles". And here, I'm a little stuck:
- If such a relation has another attribute (such as
required
or adate
), the EMF creates an own entity for the relation - let's assumePermission_To_Role
.
then, I can "easily" create a relation, with the following code:
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();
}
Whatsoever - in this case - we don't have any additional attribute on the mapping, so the additional class is avoided by the EF Framework.
Im now trying hard to create a relation, but without success:
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();
}
This always results in an Exception, and I can't figure out why (IDs are existing and correct) ...
Exception of 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.
Inner Exception:
An error occurred while updating the entries. See the inner exception for details.
Inner Inner Exception:
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
Ideas?
Update:
SHOW CREATE TABLE Permission_to_Role;
output:
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:
As of the current comments: I enabled the output for queries generated by the EF, and found this charm - which is obviously a malformated Query:
INSERT INTO
(SELECT
Permission_to_Role.PermissionId,
Permission_to_Role.RoleId
FROM
Permission_to_Role AS Permission_to_Role
)
( PermissionId, RoleId) VALUES ( 2, 1)
The query actual should be:
INSERT INTO
Permission_To_Role
( PermissionId, RoleId) VALUES ( 2, 1)
So, I think this looks like a "bug"? As mentioned above:
Whatsoever - in this case - we don't have any additional attribute on the mapping, so the additional class is avoided by the EF Framework.
there is no intermediate Permission_To_Role
Entity, hence it seems like EF is trying to replace this table name with the query
SELECT
Permission_to_Role.PermissionId,
Permission_to_Role.RoleId
FROM
Permission_to_Role AS Permission_to_Role
EVEN upon inserts... (Maybe this works for MsSQL and is a bad implementation for the MySQL Connector?)