Sepehr Abaszadeh
Sepehr Abaszadeh

Reputation: 27

Entity Framework Core 2 one to one relationship "on one table"

I have an entity that have a one to one relationship with itself:

public class Link
{
    public long Id { get; set; }
    public long OtherLinkId { get; set; }
    public Link OtherLink { get; set; }
}

How can I define this relationship with fluent API?

My solution:

modelBuilder.Entity<Link>()
            .HasOne(x => x.OtherLink)
            .WithOne(x => x.OtherLink)
            .OnDelete(DeleteBehavior.Restrict);

but on migration, it tries to create a second OtherLink.

Upvotes: 1

Views: 1935

Answers (2)

Vivek Nuna
Vivek Nuna

Reputation: 1

You can achieve this by using a nullable ForeignKey attribute in your model class.

public class Link
{
    public long Id { get; set; }
    public long? OtherLinkId { get; set; } = null;

    [ForeignKey("OtherLinkId")]
    public Link OtherLink { get; set; }
}

Upvotes: 2

CodeNotFound
CodeNotFound

Reputation: 23230

You need to specify it. EF conventions can't find it without your help.

If you don't want to follow the convetions and need to specify it using data annotation attribute ForeignKey like below:

[ForeignKey("OtherLinkId")]
public Link OtherLink { get; set; }

Or using fluent configuration:

modelBuilder.Entity<Link>()
            .HasOne(x => x.OtherLink)
            .WithOne(x => x.OtherLink)
            .HasForeignKey(p => p.OtherLinkId);
            .OnDelete(DeleteBehavior.Restrict);

Important side note: Your foreign key property should be nullable without that you'll not be able to insert item to your table OtherLink.

Your final code should look like this:

public class Link
{
    public long Id { get; set; }
    public long? OtherLinkId { get; set; } // <- Without this you'll be unable to insert a single link.

    [ForeignKey("OtherLinkId")] // <- remove this if you use Fluent Configuration.
    public Link OtherLink { get; set; }
}

Upvotes: 0

Related Questions