Reputation:
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
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
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
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