user10378972
user10378972

Reputation:

EF core Database specific columns to nested object

I have this:

public class Foo
{
    public int Id { get; set; }
    public Bar Bar { get; set; }
}

public class Bar
{
    public int Something { get; set; }
    public int SomethingElse { get; set; }
}

and my database is like this:

CREATE TABLE [Foo](
    [Id]                 INT,
    [Bar_Something]      INT    NOT NULL,
    [Bar_SomethingElse]  INT    NOT NULL,
)

When I get the DB context with

public class DB: DbContext
{
    public DbSet<Foo> Foo { get; set; }
}

Foo.Id is mapped correctly but Bar cannot be mapped with this error System.InvalidOperationException : The entity type 'Bar' requires a primary key to be defined.

I don't want to create Bar table and give its id as FK to Foo. How can I map the columns Bar_Something and Bar_SomethingElse to Foo.Bar.Something and Foo.Bar.SomethingElse?

Upvotes: 9

Views: 4028

Answers (3)

Gibbon
Gibbon

Reputation: 2773

What you seem to be looking for is Table Splitting - the second entity of Bar will still need an ID field though it would be the same field that is used for the Foo object, meaning it will join them on a 1-1 basis perfectly.

This allows you to map the ID field of the table to multiple objects, then becoming both the principal and foreign key for the join.

you can read more about it an a quick example over Here as a pretty simple blog post demo.

This can also be done using the [Owned] attribute - the difference between using owned and simply mapping two objects to the same table is that an Owned object will only ever be a navigational property - so you wouldnt be able to just look for Bar you would always have to look for Foo and include Bar.

Depending on how you want them to behave (independent, or dependant) you have the two options for table splitting.

Upvotes: 0

Panagiotis Kanavos
Panagiotis Kanavos

Reputation: 131714

EF Core 2.0 and later support Owned entity types. By default, those are mapped using Table splitting.

In EF Core 2.1, you probably only need to add the [Owned] attribute to Bar, ie :

[Owned]
public class Bar
{
    public int Something { get; set; }
    public int SomethingElse { get; set; }
}

The owned type's properties will be mapped to fields in the same table named Property_OwnedProperty. In this case it will be Bar_Something and Bar_SomethingElse

Looks like someone designed the table with those requirements in mind.

In EF Core 2.0 you need to specify the owned type in the context configuration :

modelBuilder.Entity<Foo>().OwnsOne(p => p.Bar);

Upvotes: 10

Ranvijay Singh
Ranvijay Singh

Reputation: 366

a primary key to be defined in your Bar class.

public class Bar
{
    [Key]
    public int Something { get; set; }
    public int SomethingElse { get; set; }
}

Upvotes: -1

Related Questions