Cómo unir dos tablas en el primer enfoque de Code

i have two table, User and Friendship. i want to join this two tables so that the column TheirFriends which have UserID of all friends will have some attribute that is in User. that is i want to get each friend with all their attribute. Output will look like this Theirfriends firstname LastName UserPicture

i need this linq and lambda expression.

Usuario:

public class User
{

    public String UserID { get; set; }
    public string FirstName { get; set; }
    public String LastName { get; set; }

    public string Description { get; set; }
    public string UserPicture { get; set; }
    public string Gender { get; set; }
    public String Interest { get; set; }
    public DateTime DateOfBirth { get; set; }
    public String Email { get; set; }

Amistad

 public class FriendShip
{

    public int FriendShipID { get; set; }
    public string TheirFriends { get; set; }

    public String UserID { get; set; }
}

preguntado el 10 de marzo de 12 a las 14:03

Does this mean that the string TheirFriends represents something like a collection with a separator, like "Jim;John;Diana" and those names are UserIDs? And what is then the UserID propiedad en el FriendShip ¿clase? -

@slauma when a user add a friend is going to insert The userID of his friend in TheirFriend column and his own userID in UserID in the friendship table. so whenever i search particular user with UserID in Friendship table i will return all his or her friends. Normally when i do this in sql i use views to join them. -

You should go through the EF/MVC tutorial (asp.net/mvc/overview/models-(data) ) which shows how to to this and more. -

@Rick.Anderson-at-Microsoft.com: The link in your comment above me is broken (URL looks incomplete). -

1 Respuestas

Usted puede utilizar lo siguiente:

var usersWithFriends = context.Users
    .GroupJoin(context.FriendShips, u => u.UserID, f => f.UserID, (u, f) => new
    {
        User = u,
        Friends = f.Join(context.Users, f1 => f1.TheirFriends, u1 => u1.UserID,
            (f1, u1) => u1)
    })
    .ToList();

The result is a collection of anonymous objects and each element has a User property with a user and a Friends collection which contains all users which are friends of the given user. Because of the GroupJoin the result also contains users without friends (Friends collection is empty in this case). Roughly like so:

Element[0]:
    User -> "Jim"
    Friends -> "John" + "Diana"
Element[1]:
    User -> "John"
    Friends -> empty
Element[2]:
    User -> "Diana"
    Friends -> "John"

But this is not the Entity-Framework way to work with such a model. You should actually have a navigation property in your User clase:

public class User
{
    [Key]
    public string UserID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    //...

    public ICollection<User> Friends  { get; set; }
}

And a many-to-many relationship between the users:

modelBuilder.Entity<User>()
    .HasMany(u => u.Friends)
    .WithMany()
    .Map(x =>
    {
        x.MapLeftKey("UserID");
        x.MapRightKey("TheirFriends");
        x.ToTable("FriendShips");
    });

FriendShips would be just a join table in the database (without a FriendShipID columna, UserID y TheirFriends build a composite key instead) and not an entity in your model. User is your only entity. Then you could achieve the same result a lot easier:

var usersWithFriends = context.Users.Include(u => u.Friends).ToList();

Not only less lines of code but also a lot easier to read and understand. EF will care about the complex joining and grouping in the database when the query is translated into SQL.

Editar

You can add relationships (= rows in the link table FriendShips) by adding an existing user to the Friends colección:

using (var context = new MyContext())
{
    var user = context.Users.Single(u => u.UserID == "John");
    var friend = context.Users.Single(u => u.UserID == "Diana");

    user.Friends = new HashSet<User>();
    user.Friends.Add(friend);

    context.SaveChanges(); // will write a new row into the join table
}

Likewise you can remove a relationship (remove row from join table):

using (var context = new MyContext())
{
    var user = context.Users.Include(u => u.Friends)
        .Single(u => u.UserID == "John");
    var friend = user.Friends.Single(u => u.UserID == "Diana");

    user.Friends.Remove(friend);

    context.SaveChanges(); // will delete a row from the join table
}

It's also possible without querying the users from the database since you have the primary key values:

using (var context = new MyContext())
{
    var user = new User { UserID = "John" };
    var friend = new User { UserID = "Diana" };

    context.Users.Attach(user);
    context.Users.Attach(friend);

    user.Friends = new HashSet<User>();
    user.Friends.Add(friend);

    context.SaveChanges(); // will write a new row into the join table
}

using (var context = new MyContext())
{
    var user = new User { UserID = "John" };
    var friend = new User { UserID = "Diana" };

    user.Friends = new HashSet<User>();
    user.Friends.Add(friend);

    context.Users.Attach(user);
    // attaching friend is not necessary, it is already attached with user

    user.Friends.Remove(friend);

    context.SaveChanges(); // will delete row from the join table
}

respondido 11 mar '12, 17:03

@JED: the table will only have two columns (UserID and TheirFriends) which build a key together. - Slauma

this work fine but dont know how to add data to friendship table. - johnson duru

i have everything working but i can't insert data into the friendships table that has UserID and Thierfriends. how do i go about this. thanks - johnson duru

@JED: I have added two examples for adding/removing relationships. For more details or problems, please create a new question (it costs nothing). We are already moving away from your original question. - Slauma

@JED - You should go through the EF/MVC tutorial (asp.net/mvc/overview/models-(data) ) which shows how to to this and more. - RickAndMSFT

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.