Entity framework delete cascade on many to many detached - entity-framework

I have the concept of user and roles where User has many roles and Role has many users. If a user is in a role (using a link table generated by EF), and I try to delete it, it does not cascade, then it throws an error of : The primary key value cannot be deleted because references to this key still exist. [ Foreign key constraint name = Role_Users_Target ].
This is the code I use to delete the user:
var user = new User() { UserId = userId };
db.Users.Attach(user);
db.Users.Remove(user);
db.SaveChanges();
How do I fix this?

Related

DynamoDB - What happens when I delete a object in a GSI? Does it "Cascade" to the main table?

Let's say in my main table I have objects that have the following pattern :
Partition Key = user_user#email.com
Range Key = project_001
Role = owner
It's a simple object that says what is the role if a specific user in a specific project.
But then I want to get all user roles in a project, so I made a GSI that inverts the key orders by using Range Key Begins With "user_"
Partition Key = project_001
Range Key = user_user#email.com
Role = owner
But what happens when I delete a object in this GSI? Will it delete the respective object it replicated from the main table? Or do I need to manually keep them synchronized?
You can't delete via a GSI.
DeleteItem() only accepts the table name.
That will cascade down to the GSI.

Squeryl Foreign Key onDelete cascade doesn't work

i have a User and a Device Table. If a User connects to a Device, the Device will know its User (Foreign Key). A Device can only have one User.
I create a Foreign Key with
userToDevice.foreignKeyDeclaration.constrainReference(onDelete cascade)
it does alter the table like that
alter table Device add constraint DeviceFK10 foreign key (user_id) references User(id) on delete cascade;
Now, when i create a User, assign it to a Device and then delete the User, the user_id property at Device Table doesn't get deleted, too.
//CREATE DEVICE
val device = queries.deviceCreate("XYZ-Device", None) //None User
//ASSIGN USER TO DEVICE
update(deviceT)(d=> where(d.id === device.get.id) set(d.user_id := user.id))
//DELETE USER
userTable.deleteWhere(u=> u.id === user.id)
Why is it that it doesn't delete the Foreign Key even with on delete cascade?
EDIT:
I think i messed anything up with the relation.
Here you can see example code. Probably you can tell me what i am doing wrong here.
ShowCase on Github
EDIT2:
It seems like mysql doesn't even create the Foreign Key. I can't find any when i check localhost/phpmyadmin
I think the default table type for MySQL is MyISAM, which doesn't support foreign keys.

How to tell EntityFramework 5.0 that there's a one-to-one association between two entities?

I could go into the EDMX in design view and update the cardinality (1-, 0-, etc.) of associations, but I want to know if it is alright to do that in this scenario.
I have these two tables, let's say:
User
-----
Id
UserProfile
-------------
Id
UserId
Stuff
A single user may have just one profile. Therefore, I have set a UNIQUE constraint no the UserId column in the UserProfile table. Also, UserProfile.Id is defined as a foreign key that references User.Id.
However, in the Entity Framework model, I get the following:
class User
{
ICollection<UserProfile> UserProfiles { get; set; }
}
At first, I had the UserProfile table without any primary key of its own like this:
UserProfile
--------------
UserId
Stuff
But EntityFramework made that read-only as it needed to have a primary key on every table that you want to be made writable. So, I put an Id column in the UserProfile table as well.
UPDATE
I tried setting the multiplicit/cardinality of the association between the User table and the UserProfile table in my EDMX in the designer. However, I get this error suggesting I should turn it back to what it was, i.e. a one-to-many relationship.
Running transformation: Multiplicity is not valid in Role 'UserBasicProfile'
in relationship 'FK_UserBasicProfile_User'. Because the Dependent Role
properties are not the key properties, the upper bound of the multiplicity
of the Dependent Role must be *.
I've found a way. Well, not purely a 1-1 relationship but a 1-0..1 relationship was what I was after, which, for all practical purposes is a one-to-one relationship.
If you ever fall into this trap like I described in my question, here's what you do:
1) Remove the Id field from the dependent table, in this case the UserProfile table. Therefore, do not give it a separate primary key.
2) Instead, mark the foreign key in the dependent table as its own primary key. In this case, mark the UserId field itself as the primary key of the UserProfile table.
In addition to these two, I assume, as I outlined in the question that you've got a primary and foreign key relationship between the authority (the User table in this case) and the dependent table (the UserProfile table in this example).
So, you new table structure should look like this:
User
------
Id
UserProfile
-------------
UserId (foreign key, and also the primary key of this UserProfile table)
Stuff
Entity Framework will then recognize this 1-0..1 relationship.

EF 4.1 Many to Many Delete Parent should delete related children

EF 4.1 Database First approach.
Say I have this table schema
Users 1---M UserRoles M---1 Roles
Cascade delete is setup in the Foreign Keys
The UserRoles table has additional columns like CreatedDate so I create a model for UserRoles and map accordingly.
I end up with the following Models:
User
----
int Id
string Name
List<UserRoles> UserRoles
UserRoles
---------
int UserId
int RoleId
DateTime CreatedDate
User User
Role Role
Role
----
int Id
string Name
List<UserRoles> UserRoles
If I have my configuration correct, should I be able to delete a user and will the user roles rows be deleted WITHOUT having to clear the UserRoles collection manually?
So can I just do this:
DbContext.Entry(user).State = EntityState.Deleted;
DbContext.SaveChanges();
Or do I HAVE to do this:
user.UserRoles.Clear();
DbContext.Entry(user).State = EntityState.Deleted;
DbContext.SaveChanges();
My testing shows I HAVE to clear the child collection, but I find conflicting information that if I have cascade delete setup correctly it should work by only deleting the User.
When I DON'T clear the UserRoles I receive this error:
The relationship could not be changed because one or more of the
foreign-key properties is non-nullable
Thanks for you help in clarifying this!
You must use
DbContext.Users.Remove(user);
It is not the same thing as setting the state to Deleted. Setting the state won't mark any child objects with cascading delete setup as Deleted but Remove will do.
Setting the state to Deleted should work IF no children are loaded into the context because EF will send only a DELETE statement for the parent to the database and the database will delete the children as well due to the cascading delete in the database.
IF however you have loaded children into the context setting the state on the parent to Deleted won't set the state of the children. EF will throw the exception, it's not the database who complains.
You should be able to specify that deleting a Role or User will in turn delete the child grants. You can use the WillCascadeOnDelete() method on the fluent DbModelBuilder API:
modelBuilder.Entity<UserRoles>
.HasRequired(d => d.User)
.WithMany(p => p.UserRoles)
.HasForeignKey(d => d.UserId)
.WillCascadeOnDelete();
modelBuilder.Entity<Role>
.HasMany(p => p.UserRoles)
.WithRequired(d => d.Role)
.HasForeignKey(d => d.RoleId)
.WillCascadeOnDelete();
With this setup, deleting a User or a Role should also delete all of the UserRoles.

Problem adding foreign key in simple setup

I have two tables
Users
Users_Role
I decided to try to add a foreign key as to my understanding it will let me cascade the delete procedure when removing a user from Users (as well as enforce integrity).
So via Management Studio I right clicked my Users_Role table, Design, then went into Relationships. I added a new relationship between the two tables as such:
Foreign Key Base Table: Users_Role
Foreign Key Columns: UserID
Primary/Unique Key Base: Users
Primary/Unique Key columns: ID
When I then try to save, I get the following error:
'Users' table saved successfully
'Users_Role' table
- Unable to create relationship 'FK_Users_Role_Users'.
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK_Users_Role_Users". The conflict occurred in database "db", table "dbo.Users", column 'ID'.
I'm not sure what's going on. Adds the relationship to Users, but not Users_Role? The only thing special about Users_Role is that my primary key consists of two columns, UserID and Role (the only two columns in the table, if that matters). Otherwise, nothing special.
This error means that in your current database, you have entries in the "Users_Role" table which have a "UserID" value that is not present in the Users table as ID.
You first need to find those "rogue" rows and either update or delete them, before you can create the foreign key to enforce referential integrity and avoid such problems in the future.
You can find those by issuing this command:
SELECT * FROM Users_Role
WHERE UserID NOT IN
(SELECT DISTINCT ID FROM Users)