0

This is what i was trying to achieve but entity framework didn't let me do this:

    modelBuilder.Entity<ApplicationUser>()      
                    .HasMany(u => u.Following)
                    .WithMany(u => u.Followers)
                    .Map(m =>
                            {
                                m.ToTable("FollowTables");
                                m.MapLeftKey("UserId");
                                m.MapRightKey("FollowId");
                            });

But if i use this code then in database, table is created but with no primary key in it.only two column got created. If i use this code then proper table is created with primary key too in it.

    public class FollowTable
    {
    [Key]
    public int autoId { get; set; }
    [ForeignKey("User")]
    public int UserId { get; set; }
    public ApplicationUser User { get; set; }
    [ForeignKey("Follow")]
    public int? FollowId { get; set; }
    public ApplicationUser Follow { get; set; }
    }

here, autoId is primary key and UserId and FollowId both are foreign key to ApplicationUser class where UserId is user's own id and FollowId are the ids which user is following.

  autoId  UserId  FollowId
   1        4        11
   2        4        12
   3        4        13

but my ApplicationUser class structure is something like this :

  public class ApplicationUser : IdentityUser<int, CustomUserLogin, CustomUserRole, CustomUserClaim>
{
    public string Address { get; set; }
    public ApplicationUser()
    {
        this.Followers = new HashSet<ApplicationUser>();
        this.Following = new HashSet<ApplicationUser>();
    }
    // calculated properties
    public ICollection<ApplicationUser> Following { get; set; }
    public ICollection<ApplicationUser> Followers { get; set; }

i want to use these collections badly. But this code i think is creating a new table in database named dbo.ApplicationUserApplicationUsers with columns ApplicationUser_Id and ApplicationUser_Id1. i dont want this table.also my code is too entering data into this table like this follow function:

   public virtual bool Follows(int userId, int accountId)
    {
        var targetUser = _context.Users
          .Where(u => u.Id == accountId && u.Id != userId)
          .Select(u => new
          {
              User = u,
              CanFollow = u.Followers.All(f => f.Id != userId)
          })
          .FirstOrDefault();
        if (targetUser == null || !targetUser.CanFollow) return false;
        var currentUser = _context.Users
          .Include(u => u.Following)
          .FirstOrDefault(u => u.Id == userId);
        if (currentUser == null) return false;
        if (currentUser.Following.All(u => u.Id != accountId))
        {
            currentUser.Following.Add(targetUser.User);
            _context.SaveChanges();
            return true;
        }
        return false;
    }

Now, suggest me how to configure mapping with or without fluent api.i want to enter data in follow table not in table which was auto generated.

duke
  • 1,816
  • 2
  • 18
  • 32

1 Answers1

0

You're conflating two separate relationships. If you were dealing with something like "Friends", then that's a straight M2M: by virtue of me being your friend, you are also my friend. However, a user could follow many people and be followed by none, that means you need two separate relationships to to track that.

public class ApplicationUser
{
    ...

    public virtual ICollection<ApplicationUser> Following { get; set; }
    public virtual ICollection<ApplicationUser> Followers { get; set; }

    public class Mapping : EntityTypeConfiguration<ApplicationUser>
    {
        HasMany(m => m.Following).WithMany();
        HasMany(m => m.Followers).WithMany();
    }
}

Then in your context:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Configurations.Add(new ApplicationUser.Mapping());
}

Entity Framework will handle the join tables. You don't need to worry about that, unless you need an M2M with a payload, like the date someone started following or the user started following someone else.

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
  • Dont know it will work or not will try it asap i got back to my lappy thnks for the help @Chris Pratt – duke Jan 07 '16 at 13:58
  • well i tried this as u said, its now creating two extra tables in database dbo.ApplicationUserApplicationUser1 and dbo.ApplicationUserApplicationUsers u can try too @Chris Pratt – duke Jan 08 '16 at 07:28
  • As it should. You have to two M2M relationships, so you need two join tables. – Chris Pratt Jan 11 '16 at 17:06