I have the following entities structure-
ParameterDefinition-->ParameterGroup-->Parameter
ParameterDefinition-->ParameterOperations
Also there is a map table with 2 FKs- Parameter & ParameterOperation (many to many entity).
The problem is that when i try to delete ParameterDefinition it first tries to delete ParameterGroup which can't be done because FK constraint to Parameter.
All my associations are set On Delete- Cascade.
How can i solve this so first it will start from the Map Entity , than other entities according the FKs ?
From everything I've read, you have to both set your FKs in the database to cascade on delete. The EDMX file won't pick this up when you update it, so you also have to set cascade on delete on the FKs in the EDMX file. Did you set the cascade on delete option at both the database level and the EDMX level? I'm reading it as you've only done this at the EDMX level, but I could be wrong.
I'm not a big fan of setting all my FKs to cascade on delete, so I just had to delete things in the correct order.
Related
I have a #ManyToOne relation between Workpackages and Projects. Where a project can have one to many workpackages.
My Workpackage entity refers to the Project one like such:
#NotNull
#ManyToOne(targetEntity = ProjectEntity.class)
private ProjectEntity project;
Therefore each line in my Workpackage table references the id of a certain project.
But when I try to delete a project, I get a foreign key constraint (which makes sense, since my workpackage depends on a project, and should be deleted before the former is deleted).
But a cascade = CascadeType.REMOVE won't work since I am deleting my project and not my Workpackage. Would there be a way to delete the Workpackage related to a certain project upon its deletion?
Being new to Hibernate, nothing obvious comes to mind other than going through every Workpackage and deleting them one by one.
ON DELETE CASCADE : if you delete a project row in table Project the engine will delete as well the related workPackages. This can used to make automatic cleanups on secondary tables.
When declaring schema, do the following thing
alter table Workpackage add constraint constraintName
foreign key (id) references Project(id) on delete cascade
you will have to set child's object as null explicitly.
for (Workpackage child : project.getWorkpackages()) {
child.setProject(null);
}
session.delete(OwningSide);
Entity Framework 6 Casscading Deletes and DropForeignKey fails on auto generated constraint name
I've been running into a bit of an issue with Entity Framework and cascade deletes between two tables on several one-to-many relationships.
Initially it looked like the correct path to take was to configure the table mappings with the OnModelCreating method of DbContext turning off cascade delete in a manner such as
modelBuilder.Entity<SourceTable>()
.HasOptional(x => x.NavigationProperty)
.WithOptionalDependent()
.WillCascadeOnDelete(false);
This however did not work throwing an exception stating
Cannot delete or update a parent row: a foreign key constraint fails...
More research lead me to believe that this is because all affected entities must be loaded into the context (eager fetched) so that entity framework may set the FK references to null as part of the transaction. This is not practical for my needs based on the size of the relational graph I'd be dealing with.
My next approach was to modify the Seed method of the Configuration class and run some arbitrary SQL to drop the Foreign Key constraint and re-add it as a ON DELETE SET NULL constaint. This worked in most cases, however one of the consraints has what appears to be an auto generated unpredicatable name that is diffrent on each call of Update-Database. Given that the name can't be predicted the ALTER statments aren't particualr helpful
context.Database.ExecuteSqlCommand(#"ALTER TABLE SourceTable DROP FOREIGN KEY FK_9405957d032142c3a1227821a9ed1fdf;
ALTER TABLE SourceTable
ADD CONSTRAINT FK_ReasonableName
FOREIGN KEY (NavigationProperty_Id) REFERENCES NavigationProperty (Id) ON DELETE SET NULL;");
Finally, I've taken the apprach to use the migration functionality (DbMigration) and override Up method and leveraging the DropForeignKey method along side more explicit SQL to re-add the constraint (EF does not appear to provide a factility to create a ON DELETE SET NULL constraint).
DropForeignKey("SourceTable", "NavigationProperty_Id", "DestinationTable");
Sql("ALTER TABLE SourceTable ADD CONSTRAINT FK_ReasonableName FOREIGN KEY (NavigationProperty_Id) REFERENCES DestinationTable (Id) ON DELETE SET NULL;");
This works great, up until I encounter the constraint with the auto generate name. At this point the DropForeignKey method fails with an exception that is swallowed up by
System.Runtime.Serialization.SerializationException: Type is not resolved for member 'MySql.Data.MySqlClient.MySqlException,MySql.Data...
When dumping the migration to a SQL script file it becomes clear that the DropForeignKey simply generates a FK with a more predictable, non-ambiguous byte stream array.
Is there a proper EF Code First approach to solve the problem of setting FK column values to null when deleting the refrenced row, or am I stuck having to hand code SQL in order to gain this functionality?
I am using VS2012 and the Entity designer to generate both the database and the models. I have a very basic scenario of Table1 to Table1and2JoinTable to Table2. Something like Students, Classes, StudentClasses. You can have many students in many classes. I would like to have a cascading delete. So if you delete a student any rows in the StudentClass join table are deleted for that student id. Same for deleting a class any rows in the StudentClass are deleted for that class id. After setting up the many to many association in the designer and setting the cascade delete options you get the following error when you attempt to generate the database:
Error 132: End 'Student' on relationship 'Model1.StudentClass' cannot have operation specified since its multiplicity is ''. Operations cannot be specified on ends with multiplicity ''.
Here is a small example:
Here is the association created:
And the resulting error messages:
Here is a portion of the SQL code for generating the database tables:
-- Creating foreign key on [Students_Id] in table 'StudentClass'
ALTER TABLE [dbo].[StudentClass]
ADD CONSTRAINT [FK_StudentClass_Student]
FOREIGN KEY ([Students_Id])
REFERENCES [dbo].[Students]
([Id])
ON DELETE NO ACTION ON UPDATE NO ACTION;
-- This should be ON DELETE CASCADE ON UPDATE NO ACTION;
GO
-- Creating foreign key on [Classes_Id] in table 'StudentClass'
ALTER TABLE [dbo].[StudentClass]
ADD CONSTRAINT [FK_StudentClass_Class]
FOREIGN KEY ([Classes_Id])
REFERENCES [dbo].[Classes]
([Id])
ON DELETE NO ACTION ON UPDATE NO ACTION;
-- This should be ON DELETE CASCADE ON UPDATE NO ACTION;
GO
I know how to work around this by just editing the database script and add in the on delete cascade option. But, I don't want to do this because I am going to come back to the designer many times as the project grows and I don't want to have to remember this step every time.
Has anyone figured out how to resolve this?
It seems to be an edmx restriction, which I don't really understand. Code-first is perfectly capable of generating a junction table with two cascading ON DELETE constraints, but model-first and database-first do not allow the same configuration in the edmx. Normally, cascade actions are configured on the 'one' end of an association. Maybe it is too complex to check the validity of cascade actions on '*' ends (only when both ends are '*').
For the cascaded delete to happen with a context based on an edmx model, you have to load a parent and its children and then delete the parent.
var cls = db.Classes.Include(c => c.Students).Single(c => c.Id = 1);
db.Classes.Remove(cls);
db.SaveChanges();
The executed SQL statements show that the Class is fetched from the database in a JOIN statement with Student. Then the StudentClasss and the Class are deleted respectively.
Obviously, this is much more expensive than enabling cascaded delete in the database.
The work-around to modify the DDL each time after is was generated is not attractive, of course. But I think the only alternative is to make StudentClass part of the model and configure cascaded delete on the 'one' ends of the new associations. Or go code-first.
First of all make sure that you have an ON DELETE CASCADE specified in your Foreign Keys on database side.
I had similar problem and just adding ON DELETE CASCADE solve it instead of setting End1OnDelete and End2OnDelete properties.
I have a junction table with and idenity primary key columns to realize a many to many relationship. Visual Studio automatically detects it as a many to many relationship and the junction table is not an entity.
How can i realize it that also this table is generated as an entity? I need this for breeze.js .
You just need to add additional columns (or properties) to that table (or model).
You said that your table has acolumn named ID and it's the primary key withe IsIdentity set to true. It must works, I'm using this approach...
There must be a problem or missing with your table definition. However, if all are OK, just add a nullable column in your table and update your model from database. The problem will go away.
In my MS SQL Server 2008 database I have self-referenced table with categories for hierarchy (ID and ParentID). Table have a self Foreign Key constraint and "Instead of Delete" trigger to perform deleting the full node with its children.
To manage data I'm using Entity Framework (4.3), with the model generated from DB with self-tracking entities and ObjectContext (generated by VS template). EDM also have self-referenced association on "category" entity.
I am faced with problem when trying to delete any parent row that has at least one child row.
After I call:
Entity.MarkAsDeleted();
Context.SaveChanges();
In SQL Server Profiler I see that EF first generates an update statement to set ParentID of child row(s) to null and then deletes parent row! Of course cascade rule in DB doesn't work and child nodes remains both in EF context and DB.
I've tried to set association rule "On delete" to "Cascade" and to "None" but it doesn't make sense...
How can I perform a cascade delete in a self-referenced table with EF, or at least how to prevent EF from updating parent IDs of child rows?
PS: here I found exactly the same problem without answer (MSDN)