2012-03-10 79 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