Efcore: Avoiding HasForeignKey when fluently defining One-To-One Relationship

Created on 16 Oct 2017  路  1Comment  路  Source: dotnet/efcore

(EF Core 2.0)

I am using Entity Framework Core 2.0 without Schema Migration as I want to define the schema myself. I have a one-to-one relationship between Foo and Bar and the following schema:

````
Foo:
Id UNIQUEIDENTIFIER PRIMARY KEY NOT NULL

Bar:
ID UNIQUEIDENTIFIER PRIMARY KEY NOT NULL,
FooId UNIQUEIDENTIFIER,
CONSTRAINT fk_bar_foo FOREIGN KEY (FooId) REFERENCES Foo(Id)
````

Now I can use the Fluent API to model a one-to-one relationship:
```C#
modelBuilder.Entity()
.HasOne(e => e.Foo)
.WithOne(e => e.Bar)
.HasForeignKey(e => e.FooId);

While this does work, I do not understand why Entity Framework Core forces me to have a FooId Property on the Bar Entity:
```C#
    class Bar
    {
        public Guid FooId { get; protected set; }

        public Foo Foo { get; protected set; }
    }

There is already the Foo property and the schema foreign key is ready to use within the DB. Thus, I do not see the reason why EF Core enforces yet another ID property on the entity. Any ways to avoid the FooId property?

Why I want to avoid it: I am enforcing a Domain Driven Design with a clear business model. So unlike most EF Core tutorial authors out there, I am not a fan of public getters/setters everywhere and I am not a fan of inconsistent models. Having both public properties on my entities means I have to write logic to keep both in sync. E.g. when dealing with new, yet transient objects which were not populated by EF Core before.
And I do not see why it should be neccessary here.

Any ideas? Thank you in advance.

closed-question

Most helpful comment

@axio-marco EF needs to know which end of the relationship is the principal and which end is the dependent--in other words, where the FK will be located when mapped to a database. However, this does not require that you actually have an FK property in your C# classes. For example, if you remove the FK property from Bar and map the relationship like this:
C# modelBuilder.Entity<Bar>() .HasOne(e => e.Foo) .WithOne(e => e.Bar) .HasForeignKey<Bar>("FooId");
then the FK property will be created as a shadow property that is used for the database mapping but does not appear in the C# classes.

>All comments

@axio-marco EF needs to know which end of the relationship is the principal and which end is the dependent--in other words, where the FK will be located when mapped to a database. However, this does not require that you actually have an FK property in your C# classes. For example, if you remove the FK property from Bar and map the relationship like this:
C# modelBuilder.Entity<Bar>() .HasOne(e => e.Foo) .WithOne(e => e.Bar) .HasForeignKey<Bar>("FooId");
then the FK property will be created as a shadow property that is used for the database mapping but does not appear in the C# classes.

Was this page helpful?
0 / 5 - 0 ratings