How to disable cascade delete for link tables in EF code-first?
I got the answer. :-) Those cascade deletes were being created because of ManyToManyCascadeDeleteConvention
. You need to remove this convention to prevent it from creating cascade deletes for link tables:
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
EF4.1 Code First : How to disable delete cascade for a relationship without navigation property in dependent entity
You must configure it from the other side of the association:
modelBuilder.Entity<ParentEntity>()
.HasMany(p => p.Children)
.WithRequired()
.HasForeignKey(c => c.ParentEntityId)
.WillCascadeOnDelete(false);
Disable cascade delete on EF Core 2 globally
Unfortunately EF Core currently (latest at this time v2.0) does not expose a good way to control the conventions globally.
The default EF Core 2.0 convention is to use DeleteBehavior.Cascade
for required and DeleteBehavior.ClientSetNull
for optional relationships. What I can suggest as workaround is a typical metadata model loop at the end of the OnModelCreating
override. In this case, locating all the already discovered relationships and modifying them accordingly:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// ...
var cascadeFKs = modelBuilder.Model.GetEntityTypes()
.SelectMany(t => t.GetForeignKeys())
.Where(fk => !fk.IsOwnership && fk.DeleteBehavior == DeleteBehavior.Cascade);
foreach (var fk in cascadeFKs)
fk.DeleteBehavior = DeleteBehavior.Restrict;
base.OnModelCreating(modelBuilder);
}
Entity framework code first:How to disable delete cascade for property attribute?
You cannot do that by attribute. Use EF fluent API or remove this OneToManyCascadeDeleteConvention convention.
Understanding disabling on cascade delete using fluent api
On cascade delete
Let's say there is another type link to your attendance. So in database this other type (table) will have a foreign key to the Attendance
table.
If you try to delete an Attendance
record in the datatable, it will fail if this record is used in the other table.
With the cascade delete it will delete all related records besides the Attendance record.
If the cascade delete is not enable the deletion will fail because other records need this Attendance record.
Entity
No matter if you generate the database from your code or if the database already exists, your C# class representing the table cannot provide all information (for example if you do not follow the convention, EF cannot know which field is the primary key, which field is not nullable (see next point), or if the table name will match the class name).
With the modelBuilder.Entity<Attendance>()
you will help EF to build his "inner model of how the database will looks like". In this case you provide to EF additional information about the "Attendance" type.
So you could warn EF this table is in another schema or the table name is different...
Potentially you could do that for all your entities/tables.
IsRequired
(not used in your example but I confond IsRequired
and HasRequired
so I let the explanation here)
The IsRequired
is used with nullable types. In database you can have a type "varchar(x) not null" and in C# it will be a "string". But string can be nullable in C# so the HasRequired
is a configuration that will tell your ORM "Yes the type is nullable but in my configuration it should not be the case".
So when EF will generate the database the type will be "not null" or when your EF will validate the entity before calling the database, that check will be done.
HasRequired
It's the same concept as the IsRequired
but a little more complex since it's used when there is multiple tables involved. For example Contract and Customer, a contract is owned by one customer but a customer can have multiple contracts. So in the database Contract table will have a foreign key to Customer and in the class Contract will have a (navigation) property named Customer.
public class Contract
{
public Customer Customer { get; set; }
}
public class Customer
{
}
modelBuilder.Entity<Contract>()
.HasRequired(c => c.Customer)
This configuration will indicate Contract have a navigation property to Customer and this is a required one meaning the foreign key cannot be null. If you want it to be nullable you should use HasOptional
.
WithMany
Now you configured the HasRequired, you have the WithMany. This one will indicate you can have multiple Contract for a Customer (Contract has a required Customer who have many Contracts : It's a "one to many" relationship). But it also indicates the Customer does not care about the contracts:
public class Customer
{
}
Here you can see the Customer class does not have a (navigation) property to the contracts. If you don't need the Customer object to be able to reach the contracts this is perfectly fine.
Now if you want to have that ability you will need to do this :
public class Customer
{
public List<Contract> Contracts { get; set; }
}
modelBuilder.Entity<Contract>()
.HasRequired(c => c.Customer)
.WithMany(cu => cu.Contracts)
In that case you indicate Contract have a relationship required to Customer and this relation from the Customer object point of view lead to "Contracts" property.
Entity Framework (EF) Code First Cascade Delete for One-to-Zero-or-One relationship
You will have to use the fluent API to do this.
Try adding the following to your DbContext
:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>()
.HasOptional(a => a.UserDetail)
.WithOptionalDependent()
.WillCascadeOnDelete(true);
}
Related Topics
How to Change the Color of Winform Datagridview Header
Why Won't Anyone Accept Public Fields in C#
Problems Overwriting (Re-Saving) Image When It Was Set as Image Source
How to Drag a Usercontrol Inside a Canvas
Gracefully Handling Corrupted State Exceptions
C# ASP.NET Write File to Client
How to Asynchronously Read the Standard Output Stream and Standard Error Stream at Once
Working with Appdomain.Assemblyresolve Event
How to Convert Date Format to Dd-Mm-Yyyy in C#
Add Vertical Scroll Bar to Panel
Check If a Property Exists in a Class
Giving Application Elevated Uac
Write PDF Stream to Response Stream
Convert Time Span Value to Format "Hh:Mm Am/Pm" Using C#
The Entity or Complex Type ' ' Cannot Be Constructed in a Linq to Entities Query