2012-03-10 34 views
0

我有两个表,User和Friendship。我想加入这两个表,以便具有所有朋友的用户ID的列TheirFriends将具有某些属于User的属性。那就是我想让每个朋友都拥有他们的属性。 输出看起来像这样 他们的朋友的名字姓氏用户图片如何在代码第一个方法中加入两个表

我需要这个linq和lambda表达式。

用户:

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; } 

友谊之品

public class FriendShip 
{ 

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

    public String UserID { get; set; } 
} 
+0

这是否意味着TheirFriends'表示类似的隔膜集合,如字符串'“吉姆,约翰,戴安娜”,这些名称是' UserIDs'?那么FriendShip类中的'UserID'属性是什么? – Slauma 2012-03-10 15:01:16

+0

@slauma当一个用户添加一个朋友时,他会在FriendsFriend列中插入他的朋友的userID,并在友谊表中的UserID中插入他自己的用户ID。所以无论何时我在友谊表中搜索具有UserID的特定用户,我都会返回所有他或她的朋友。通常,当我在SQL中这样做时,我使用视图来加入它们。 – JED 2012-03-10 15:15:39

+0

您应该阅读EF/MVC教程(http://www.asp.net/mvc/overview/models-(data)),其中介绍了如何实现此目的以及更多。 – RickAndMSFT 2012-03-11 18:36:10

回答

3

您可以使用以下方法:

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(); 

结果是匿名的对象的集合,每个元素都有一个User性质与一个用户和一个包含所有用户的Friends集合这是给定用户的朋友。由于GroupJoin的结果还包含没有朋友的用户(Friends集合在这种情况下为空)。大致如下:

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

但是,这不是实体框架的方式来处理这样的模型。你应该确实有一个导航属性在User类:

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; } 
} 

而且用户之间的许多一对多的关系:

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

FriendShips将在数据库只是一个连接表(不一个FriendShipID列,UserIDTheirFriends改为创建一个组合键),而不是模型中的实体。 User是您唯一的实体。那么你可以轻松达到相同的结果:

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

不仅少了几行代码,而且更容易阅读和理解。当查询翻译成SQL时,EF将关心数据库中复杂的连接和分组。

编辑

您可以通过增加现有用户为Friends集合(在链接表FriendShips =行)添加关系:

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 
} 

同样,你可以删除的关系(删除行来自连接表):

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 
} 

也可以不询问th从数据库E中的用户,因为你有主键值:

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 
} 
+0

谢谢,我朋友的桌子会是什么样子。 – JED 2012-03-10 19:37:10

+0

@JED:表格将只有两列(UserID和TheirFriends),它们构成一个键。 – Slauma 2012-03-10 20:01:45

+0

非常感谢你。你的第二个建议工作正常 – JED 2012-03-10 22:01:51

相关问题