-1

I am trying to do a database model for my social network school project. I am using Entity Framework 6. The problem is how should I model my Friendship and Chat entity.

I get this error:

Unhandled Exception:
System.Data.Entity.ModelConfiguration.ModelValidationException: One or more validation errors were detected during model generation:

Friendship_Chat_Source: : Multiplicity is not valid in Role 'Friendship_Chat_Source' in relationship 'Friendship_Chat'. Because the dependent role properties are not the key properties, the upper bound of the multiplicity of the dependent role must be '*'.

It has probably something to do with this: EF Code-First One-to-one relationship: Multiplicity is not valid in Role * in relationship

I don't really get it how should I do it here. Even if I get rid off this error somehow (different db model), entity framework in Friendship table creates User_Id column as a foreign key, and I dont really know why it does it (I don't want it there). But I really feel that my model should look like this, not different. So I want to really figure out, how should I edit this model. However if you have different model idea I would also appreciate it.

User entity:

public class User
{
    public int Id { get; set; }

    [Required, MinLength(1), MaxLength(50)]
    public string NickName { get; set; }

    [Required, MinLength(6), MaxLength(50)]
    public string PasswordHash { get; set; }

    #region Settings

    //true if anyone can see user posts
    public Visibility PostVisibilityPreference { get; set; } = Visibility.Visible;

    #endregion

    #region Navigation properties

    public virtual HashSet<Friendship> Friendships { get; set; }
    public virtual HashSet<Post> Posts { get; set; }
    public virtual HashSet<GroupUser> GroupUsers { get; set; }
    public virtual HashSet<Comment> Comments { get; set; }

    #endregion
}

Friendship entity:

public class Friendship
{
    #region Primary keys

    public int User1Id { get; set; }
    public int User2Id { get; set; }

    #endregion

    [Required]
    public DateTime FriendshipStart { get; set; }

    #region Foreign keys

    //defined using fluent api in MyDbContext:
    //User1Id
    //User2Id
    //and

    [ForeignKey("Chat")]
    public int? ChatId { get; set; }

    #endregion

    #region Navigation properties

    public virtual User User1 { get; set; }
    public virtual User User2 { get; set; }
    public virtual Chat Chat { get; set; }

    #endregion
}

With this overrided function OnModelCreating in MyDbContext:

protected override void OnModelCreating(DbModelBuilder builder)
    {
        builder.Entity<Friendship>()
            .HasKey(k => new { k.User1Id, k.User2Id });

        builder.Entity<Friendship>()
            .HasRequired(u => u.User1)
            .WithMany()
            .HasForeignKey(u => u.User1Id);

        builder.Entity<Friendship>()
            .HasRequired(u => u.User2)
            .WithMany()
            .HasForeignKey(u => u.User2Id)
            .WillCascadeOnDelete(false);
    }

Chat entity:

public class Chat
{
    public int Id { get; set; }

    #region Foreign keys

    public int? FriendshipUser1Id { get; set; }
    public int? FriendshipUser2Id { get; set; }

    #endregion

    #region Navigation properties

    public virtual HashSet<Message> Messagges { get; set; }

    [ForeignKey("FriendshipUser1Id, FriendshipUser2Id")]
    public virtual Friendship Friendship { get; set; }

    #endregion
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459

1 Answers1

0

If I understand your model right. 1 friendship has 1 user1 and 1 user2. Your settings are excluded.

builder.Entity<Friendship>()
        .HasRequired(u => u.User1)
        .WithMany()
        .HasForeignKey(u => u.User1Id);

It means user1 has many... (many what?). Model doesn't have any list that could accept these settings. Your model has only single objects.

If you want it one to one/zero:

builder.Entity<Friendship>()
        .HasRequired(u => u.User1)
        .WithRequiredDependant(u => u.User2)
      or
        .WithRequiredPrincipal(u => u.User2)
      or
        .WithOptional(u => u.User2)

You can also try composite key for example: Creating Composite Key Entity Framework

Also I suggest you to use or Fluent API or Data Annotation convention. It will make your code more readable.

LadyHail
  • 91
  • 1
  • 5
  • i literally made it like this guy suggested: https://stackoverflow.com/questions/13896503/how-should-i-model-friendships-between-users-with-ef-code-first – Marcello Mraz Oct 14 '17 at 17:48
  • This is not the main issue. The error i get is between friendship and chat entity. Btw. I tried to use .WithRequired...() methods as you have written above, but they doesnt work like that. It doesnt give me u => u.User2 option (instead intellisense gives me u => u.[any property of User class]. And I dont want to use composite primary key either. – Marcello Mraz Oct 15 '17 at 13:05