Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two same class types in entity framework class issue

I am implementing feature that allows users to follow each other. I have database tables:

User{UserId, FirstName, LastName etc.}
Followings{FollowerUserId, FollowingUserId, CreatedOnDate etc.}

So I added EF class:

public class Follow
    {
        [Key, Column(Order = 1)]
        public Guid FollowerUserId { get; set; }
        [Key, Column(Order = 2)]
        public Guid FollowUserId { get; set; }        
        public DateTime CreatedOnDate { get; set; }

        public virtual User Follower { get; set; }
        public virtual User Following { get; set; }
    }

The last two virtual properties couse issue. When I call:

var model = con.Follows.Where(x => x.FollowerUserId == uid);

I get following exception:

Invalid column name 'Following_UserId'.

The issue is probably caused because of two User objects in one class. Any idea how to workaround this?
UPDATE

public class User
    {

        public Guid UserId { get; set; }
        ...
        public virtual ICollection<Follow> Following { get; set; }
        public virtual ICollection<Follow> Followers { get; set; }
    }
like image 711
1110 Avatar asked Oct 08 '22 09:10

1110


1 Answers

I think the reason is that the foreign key properties (FollowerUserId and FollowUserId) and navigation properties (Follower and Following) do not respect the naming conventions so that EF is unable to recognize the first properties as foreign keys. You can fix the problem by specifying the FK properties explicitly using the [ForeignKey] attribute:

public class Follow
{
    [Key, Column(Order = 1), ForeignKey("Follower")]
    public Guid FollowerUserId { get; set; }
    [Key, Column(Order = 2), ForeignKey("Following")]
    public Guid FollowUserId { get; set; }        

    public DateTime CreatedOnDate { get; set; }

    public virtual User Follower { get; set; }
    public virtual User Following { get; set; }
}

Edit

A least the second property doesn't respect the naming convention, the first one looks OK. So, alternatively you can fix the problem by renaming the second FK property FollowUserId into:

public Guid FollowingUserId { get; set; }        

...because the navigation property is called Following.

Edit 2

About your UPDATE: You need to add the [InverseProperty] attribute to tell EF which navigation properties belong together:

public class Follow
{
    [Key, Column(Order = 1), ForeignKey("Follower")]
    public Guid FollowerUserId { get; set; }
    [Key, Column(Order = 2), ForeignKey("Following")]
    public Guid FollowUserId { get; set; }        

    public DateTime CreatedOnDate { get; set; }

    [InverseProperty("Followers")]  // refers to Followers in class User
    public virtual User Follower { get; set; }
    [InverseProperty("Following")]  // refers to Following in class User
    public virtual User Following { get; set; }
}
like image 111
Slauma Avatar answered Oct 13 '22 12:10

Slauma