How to Model Entity Framework Entity/Mapping With Only One-Way Navigation
Asked Answered
S

2

18

Using EF 5, Code First.

I'd like to model my entities such that the navigation properties only exist on one side of the relationship.

So if I have a table Widget, and a table WidgetType:

public class Widget
{
    public int Id { get; set; }
    public int WidgetTypeId { get; set; }
    public WidgetType WidgetType { get; set; }
}

public class WidgetType
{
    public int Id { get; set; }
    //note there is no collection of Widgets here
}

public class WidgetMap : EntityTypeConfiguration<Widget>
{
    public WidgetMap()
    {
        HasKey(t => t.Id);
        //totable, etc.

        HasRequired(t => t.WidgetType); //what else is needed?
    }
}

I will never want to fetch widgets from the perspective of widgetType, so it makes sense (to me anyway) to not have the navigation property on the WidgetType entity.

How do I complete the mapping code noted in the code sample without having to add a property to WidgetType? Is this possible?

Swanee answered 29/5, 2013 at 15:17 Comment(7)
Does the solution have to be fluent?Allanite
I would say strongly preferred. I would rather have the properties go two way than to have it non-fluent.Swanee
Okay, have you tried HasRequired(t => t.WidgetType).WithRequired();?Allanite
I haven't--my thinking is that the framework will have no way of knowing what the foreign key is? Don't I have to specify the foreign key somehow?Swanee
Oh, I see now. I can then specify HasForeignKey(t => t.xxxx). Let me try that.Swanee
Seemed to work--want to add this an an answer?Swanee
Added :). Not sure where you put your HasForeignKey though if you want to edit my answer?Allanite
A
13

As requested in comments, here's my answer.

You should try:

HasRequired(t => t.WidgetType).WithRequired().HasForeignKey(t => t.FKField);
Allanite answered 29/5, 2013 at 17:45 Comment(1)
Edited to add foreign key bit. This seems to work, although I am a little concerned that EF does some convention-based mapping, so it's not completely impossible that it works based on conventions, and is actually ignoring this code. :)Swanee
C
19

I know there is an accepted answer, but the above solution didn't work for me and I had to tweak it some.

I'm using Entity Framework 6 and had a similar issue. I had a table called BaseEntity that had a CreatedByID field that pointed to my UserAccount table.

This created an ICollection of type BaseEntity in my UserAccount class. I was able to resolve this by using the following code in my BaseEntity mapping:

this.HasOptional(t => t.UserAccount)
    .WithMany()
    .HasForeignKey(t => t.CreatedByID);

I was then able to remove the collection of BaseEntity from the UserAccount class which created a uni-directional one-to-many mapping in EF6.

The UserAccount entry is optional because UserAccount inherits from BaseEntity. Make sure to use HasRequired() if this is a required attribute in your model.

Characharabanc answered 21/12, 2014 at 20:19 Comment(0)
A
13

As requested in comments, here's my answer.

You should try:

HasRequired(t => t.WidgetType).WithRequired().HasForeignKey(t => t.FKField);
Allanite answered 29/5, 2013 at 17:45 Comment(1)
Edited to add foreign key bit. This seems to work, although I am a little concerned that EF does some convention-based mapping, so it's not completely impossible that it works based on conventions, and is actually ignoring this code. :)Swanee

© 2022 - 2024 — McMap. All rights reserved.