Question

J'ai un utilisateur qui peut avoir une collection d'utilisateurs qu'il aime ...

Un autre utilisateur peut avoir une collection d'utilisateurs qu'il aime ...

Si l'utilisateur A aime l'utilisateur B et si l'utilisateur B aime l'utilisateur A, il peut passer du temps. J'ai besoin de vous envoyer leurs coordonnées. Comment représenter d'abord un tel modèle dans le code Framework Entity?

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

    public int? UserLikeId { get; set; }
    public virtual UserLike UserLike { get; set; }
}

public class UserLike
{
    public int UserLikeId { get; set; }

    public int UserId { get; set; }
    public virtual User User { get; set; }

    public virtual ICollection<User> LikeUsers { get; set; }
}

Ce modèle est-il correct? Je ne peux pas faire fonctionner cela.

J'ai essayé une autre façon mais cela ne fonctionne pas aussi ...

J'ai essayé d'ajouter une collection d'utilisateurs à la table utilisateur.

Pour ex:

public virtual ICollection<User> userlike { get; set; }

public class User
{
    public int UserId { get; set; }
    public virtual ICollection<UserLike> UserLikes { get; set; }
}

public class UserLike
{
    public int UserLikeId { get; set; }

    public int UserId { get; set; }
    public virtual User User { get; set; }

    public int LikeUserId { get; set; }
    public virtual User LikeUser { get; set; }
}

J'obtiens cette erreur lorsque j'essaie d'ajouter l'utilisateur et qui ils aiment:

Des modifications contradictoires du rôle «userlike_likeuser_target» de la relation «userlike_likeuser» ont été détectées.

Quelle est la meilleure façon de représenter un tel modèle?

Était-ce utile?

La solution

Vous n'avez pas vraiment besoin d'une entité distincte pour décrire la relation, le modèle d'objet ci-dessous fera l'affaire:

public class User
{
    public int UserId { get; set; }
    public string Name { get; set; }

    public int? ThisUserLikesId { get; set; }
    public virtual User ThisUserLikes { get; set; }
    public virtual ICollection<User> LikeThisUser { get; set; }
}

public class Context : DbContext
{
    public DbSet<User> Users { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>()
                    .HasOptional(u => u.ThisUserLikes)
                    .WithMany(u => u.LikeThisUser)
                    .HasForeignKey(u => u.ThisUserLikesId);
    }
}

Disons maintenant que vous avez un utilisateur dans votre main et que vous souhaitez trouver l'autre utilisateur qui aime cet utilisateur que cet utilisateur l'aime également:

using (var context = new Context())
{
    // For a given user id = 1
    var friends = (from u in context.Users
                   where u.UserId == 1
                   from v in u.LikeThisUser
                   where v.UserId == u.ThisUserLikesId
                   select new 
                   { 
                       OurUser = u, 
                       HerFriend = v 
                   })
                   .SingleOrDefault();

    ExchangeContactInfo(friends.OurUser, friends.HerFriend);
}                


Mise à jour 1:

Une association de plusieurs à plusieurs références sera cartographiée à la base de données à l'aide d'une table de jointure qui nécessite un modèle d'objet différent et une API fluide:

public class User
{
    public int UserId { get; set; }
    public string Name { get; set; }

    public virtual ICollection<User> ThisUserLikes { get; set; }
    public virtual ICollection<User> UsersLikeThisUser { get; set; }
}

public class Context : DbContext
{
    public DbSet<User> Users { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>()
                    .HasMany(u => u.ThisUserLikes)
                    .WithMany(u => u.UsersLikeThisUser)
                    .Map(c => 
                    {
                        c.MapLeftKey("UserId");
                        c.MapRightKey("OtherUserId");
                        c.ToTable("UserLikes");
                    });
    }
}


Mise à jour 2:

Comme je l'ai expliqué dans ce post, une association de plusieurs à plusieurs ne peut pas avoir de charge utile (par exemple eventID), et si c'est le cas, nous devons le décomposer à deux associations un à plusieurs avec une classe intermédiaire et je peux voir que vous avez correctement créé Cette classe (comme l'utilisateur) représente les informations supplémentaires attachées à votre association auto-référencée de plusieurs à plusieurs, mais les associations de cette classe intermédiaire ne sont pas correctes car nous devons définir exactement 2 associations de plusieurs à un, de l'utilisateur à l'utilisateur comme J'ai montré dans le modèle d'objet suivant:

public class User
{        
    public int UserId { get; set; }
    public string Email { get; set; }       

    public virtual ICollection ThisUserLikes { get; set; }
    public virtual ICollection UsersLikeThisUser { get; set; }
}       

public class UserLike
{
    public int UserLikeId { get; set; }
    public int LikerId { get; set; }
    public int LikeeId { get; set; }
    public int EventId { get; set; }

    public User Liker { get; set; }
    public User Likee { get; set; }
    public virtual Event Event { get; set; }
}

public class Event
{
    public int EventId { get; set; }
    public string Name { get; set; }
}  

public class Context : DbContext 
{
    public DbSet Users { get; set; } 
    public DbSet Events { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity()
                    .HasMany(u => u.ThisUserLikes)
                    .WithRequired(ul => ul.Liker)
                    .HasForeignKey(ul => ul.LikerId);
        modelBuilder.Entity()                        
                    .HasMany(u => u.UsersLikeThisUser)
                    .WithRequired(ul => ul.Likee)
                    .HasForeignKey(ul => ul.LikeeId)
                    .WillCascadeOnDelete(false);
    }
}

Vous pouvez maintenant utiliser la requête LINQ suivante pour récupérer tous les utilisateurs qui s'aiment:

using (var context = new Context())
{                
    var friends = (from u1 in context.Users
                   from likers in u1.UsersLikeThisUser
                   from u2 in u1.ThisUserLikes 
                   where u2.LikeeId == likers.LikerId
                   select new
                   {
                       OurUser = u1.UserId,
                       HerFriend = u2.LikeeId 
                   })
                   .ToList();
}

J'espère que cela t'aides.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top