简体   繁体   中英

Entity Framework Core - unwanted delete cascade

I have Entity Framework Core which performs additional delete which I don't want.

Model definition: I have two entities Template and TemplateVersion . A TemplateVersion are just next versions of template, so TemplateVersion has one Template (N:1 relation)

public class Template 
{
    public int Id { get; set; }
}

public class TemplateVersion
{
    public int Id { get; set; }
    public Template Template { get;set; }
}

And up to now all is clear an working good.

BUT : I want to have information on Template level which is the current version of TemplateVersion , so my Template definition now looks like ( TemplateVersion is the same as before)

public class Template 
{
    public int Id { get; set; }
    public TemplateVersion CurrentVersion { get; set;}
}

So what I want to have is N instances of TemplateVersion to point to 1 instance of Template but in the same time Template is pointing to 1 TemplateVersion

And here the magic starts: when I add one Template and one TemplateVersion all is working good.

Template ---- TemplateVersionPrevious.Template == Template

But when I add another instance of TemplateVersion pointing to the same Template (and update Template 's CurrentVersion ) suddenly first instance of TemplateVersion has its Template field nulled.

Template ---- TemplateVersionPrevious.Template == null
         ---- TemplateVersionCurrent.Template == Template

I believe that it's because Entity Framework is thinking that I have a classic 1:1 relation and only one instance of TemplateVersion can have relation to the same Template - and it's because of CurrentTemplate field.

How can I tell Entity Framework that it should not clear my TemplateVersion relation?

Additional info: once I define my TemplateVersion entity as follows

public class TemplateVersion
{
    public int Id { get; set; }
    [ForeignKey(nameof(TemplateId))]
    public Template Template { get;set; }
    public int TemplateId {get;set;}
}

it's get even more interesting: previous instance of TemplateVersion is just deleted!

Template ---- TemplateVersionCurrent.Template == Template

EF default conventions don't play well with multiple relationships between 2 entities. And data annotations don't play well with one-to-one relationships or unidirectional associations (relationships without navigation property at one of the ends).

You need to explicitly configure the desired relationships with fluent API. Since fluent API have different overloads for having/not having navigation property and it's important to use to correct overload, let say your model is exactly like this (by exactly I mean the navigation and explicit FK properties which affect the relationships, other properties are irrelevant):

public class Template 
{
    public int Id { get; set; }
    public TemplateVersion CurrentVersion { get; set; }
}

public class TemplateVersion
{
    public int Id { get; set; }
    public Template Template { get; set; }
}

the fluent configuration of the desired two relationships is as follows:

modelBuilder.Entity<Template>()
    .HasMany<TemplateVersion>()
    .WithOne(e => e.Template)
    .IsRequired();

modelBuilder.Entity<Template>()
    .HasOne(e => e.CurrentVersion)
    .WithOne()
    .HasForeignKey<Template>("TemplateVersionId")
    .IsRequired(false);

Note that you have defined circular relationship, hence one of them should be optional. I've choosen Template..TemplateVersionId to be the optional wich sounds logical to me.

Also note that for one-to-one relationships, the principal and dependent ends cannot be uniquely determined from HasOne / WithOne , so you need to use HasForeignKey and HasPrinciplaKey generic type argument to specify that (in contrast, one-to-many relationships have no such issue because the one side is always the principal and manu side is the dependent).

For more info, see Relationships .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM