msawczyn/EFDesigner

Delete options set to None throws exception

mciprijanovic opened this issue · 3 comments

Hi Michael, me again. :)
What our team noticed recently is that when we moved to v3 of the tool, we saw different behavior when sql script is generated. If Default mode is set on the relationship itself, tool now generates CASCADE delete. I think that before NO ACTION was default (but maybe I am wrong, since when setting the Default, I see no explicit delete mode set in db context, which means it is up to EF core, not related to the tool probably).
Now, if I change the option to None, I end with the following error in compile time:
'DeleteBehavior' does not contain a definition for 'NoAction'

Can you please confirm the statement about the delete behaviour and check why we can not set None as action.

Thanks.

The code, as currently generated, doesn't do anything for cascade deletes when they're set to default; that hasn't changed.

If I have
image
and don't set any delete behavior, the generated DbContext OnModelCreating will have

         modelBuilder.Entity<global::MyNamespace.Entity1>().ToTable("Entity1").HasKey(t => t.Id);
         modelBuilder.Entity<global::MyNamespace.Entity1>().Property(t => t.Id).ValueGeneratedOnAdd().IsRequired();
         modelBuilder.Entity<global::MyNamespace.Entity1>().HasMany<global::MyNamespace.Entity2>(p => p.Entity2).WithOne().HasForeignKey("Entity1Entity2Id");

         modelBuilder.Entity<global::MyNamespace.Entity2>().ToTable("Entity2").HasKey(t => t.Id);
         modelBuilder.Entity<global::MyNamespace.Entity2>().Property(t => t.Id).ValueGeneratedOnAdd().IsRequired();

The relevant code is in EFCoreModelGenerator.ttinclude for EFCore < v5 and EFCore5ModelGenerator.ttinclude for EFCore5. For the association, on the dependent side,

  • If the delete action is set to None, it'll generate OnDelete(DeleteBehavior.NoAction)
  • If the delete action is set to Cascade, it'll generate OnDelete(DeleteBehavior.Cascade)
  • Otherwise, nothing is generated

Is it possible you have a customized .ttinclude in your project that's overriding the default?

You are right, tool works as you described, so when you set Default, db context does not add OnDelete() part, but EF core obviously generates CASCADE delete by default. Here is what I generated by context.Database.GenerateCreateScript() method called on the simple example with 2 simple tables. Delete option is set to Default:
`CREATE TABLE [dbo].[Masters] (
[Id] bigint NOT NULL IDENTITY,
CONSTRAINT [PK_Masters] PRIMARY KEY ([Id])
);
GO

CREATE TABLE [dbo].[Details] (
[Id] bigint NOT NULL IDENTITY,
[Property1] nvarchar(20) NULL,
[MasterId] bigint NOT NULL,
CONSTRAINT [PK_Details] PRIMARY KEY ([Id]),
CONSTRAINT [FK_Details_Masters_MasterId] FOREIGN KEY ([MasterId]) REFERENCES [dbo].[Masters] ([Id]) ON DELETE CASCADE
);
GO

CREATE INDEX [IX_Details_MasterId] ON [dbo].[Details] ([MasterId]);
GO`

Now, everything is OK when I start new project with new tool version and EF 5, but in the case we have the old project with EF core 2.1. packages and new tool version and I try to set None action on relationship, since I don't want cascade, I get the error that DeleteBehaviorEnum does not contain NoAction value which is true since that value is introduced in EF core 3. So, tool allows me to chose None, but then tries to set this enum value which does not exist in EF core 2.1. I have chosen target framework 2.1 in the tool.

Thanks. I've changed the T4 to generate DeleteBehavior.Restrict rather than DeleteBehavior.NoAction for EFCore < 3. The change will be published in v3.0.3