Upgrading from EF Core 3.1 to EF Core 6.0 - entity-framework-core

Post upgrading from EF Core 3.1 to EF Core 6.0 we started facing the following issue:
The association between entity types 'Table1' and 'Table2' has been severed, but the relationship is either marked as required or is implicitly required because the foreign key is not nullable. If the dependent/child entity should be deleted when a required relationship is severed, configure the relationship to use cascade deletes.
Ideally following is the pseudo code
delete rows from table2 (1 row removed)
re-add rows to table2 (1 row added)
delete rows from table 1 (throws the above error)
re-add rows to table1
Note:
Till this point we are doing the above steps in in-memory (i.e. commit will happen post re-add (if any) happens to table1).
The above steps (in the pseudo code) were working just fine with EF Core 3.1.
Are there any changes in terms of 'Delete.Behavior' on EF Core 3.1 vs EF Core 6.0?

Related

Entity Framework 6 Casscade Deletes and DropForeignKey fails on auto generated constraint name

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?

Multiple database with the different (database) structure asp.net mvc

I am using MVC 5 with multiple existing database using Entity Framework 6.
The structure is almost the same in each one, except in some case there could be an additional column in a table
Example:
Database_A has table Table_A with Col_1 and Col_2.
Database_B has a newer version of data base structure and has Table_A with Col_1, Col_2 and Col_3
I know how to switch from one database to another but my problem is: How I can make my model that covers both (or more) databases structure?
If you are using entity framework and are writing code that only deals with the columns common to both databases you should have no problem. When you create your db context, just pass it the connection string for the appropriate database and the code should work fine.
Gotchas to be aware of:
1. Creating new records where Col_3 is required. Make sure to have a default value.
2. Using migrations so Entity Framework will try to keep the database matching the model.

Entity Framework Generate Database Schema (SQL) with Default Table Values

I am using EF 5 and SQL Server 2005, Model First (sort of).
By sort of, I mean that I typically build my schema in the SQL Server designer, but import the schema into EF so I have a visual view. There is often round-tripping.
However, I noticed that when I try to generate the DB schema based on the EF model, it skips all of the NEWID() default values that I have assigned as default values to my Guid IDs, but it doesn't skip the identity fields of type int.
I found this post explaining the reasoning for this:
Entity Framework 4 and Default Values
However, it doesn't answer my question: How do I get Entity Framework to generate a SQL DDL database schema with default values of NEWID() for my uniqueidentifier types?
NOTE:
I don't care about how to set them from the POCO entities and so forth (there are plenty of posts describing that) - my concern is getting the SQL DDL generated right so I can seed the database without worrying about these values going missing.
Using Entity Framework Migrations, you can use the GUID column builder and its DefaultValueSql parameter. The value of that parameter can be the string "NEWID()". This should take care of proper DDL generation.
Next you should declare these properties as database-generated using attributes or the fluent model builder, so that EF ignores the values set in your POCOs (which will be null for new objects).

Entity Framework cascade delete parent row in self-referenced table

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)

Migration issue - Kodo/OpenJPA to EclipseLink

I have an environment setup with Java EE (weblogic 10.0). Thus, Kodo/OpenJPA is used as the JPA implementation. For some reasons I want to migrate to EclipseLink.
Now I have the following issue:
Entity A -- ManyToMany -- Entity B
FetchType.Lazy, Cascade{}
JoinTable AxB
ForeignKey Constraint AxB.FK_COL -> A.PK
If I want to remove the Entity A, the entry in the join column should also be deleted
Kodo/OpenJPA -> Deletion successful, SQL Trace shows, that first the AxB rows are deleted
EclipseLink -> Deletion fails, Foreign Key Constraint violation. EL tries to delete Entity A first.
This is all in one transaction (RESOURCE_LOCAL). My thought was, that if something is within a transaction, foreign key constraints may be violated? Can the order of the deletions be changed in a way that first the Join Table rows are deleted?
I use EclipseLink 1.1.4
Thanks for your help,
Soccertrash
This issue was fixed in later versions of EclipseLink. Try 2.0, or the latest 2.3.
Otherwise remove the target object from the collection first and call flush.