2012-03-10 16 views
0

私は2つのテーブル、ユーザーと友情を持っています。私はこの2つのテーブルに参加して、すべての友人のUserIDを持つTheirFriends列がUserにある属性を持つようにします。それは私のすべての属性を持つ各友達を取得したいです。 出力は次のようになります friendsfriends firstname LastName UserPictureコードの最初のアプローチで2つのテーブルを結合する方法

この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

:データベースからの電子・ユーザーは、プライマリ・キーの値を持っているので、 UserIDs'?そして 'FriendShip'クラスの' UserID'プロパティは何ですか? – Slauma

+0

@ slaumaユーザーが友人を追加すると、FriendsFriend列に自分の友人のuserIDとfriendship表のUserIDに自分のuserIDが挿入されます。だから友だちテーブルのUserIDを持つ特定のユーザーを検索すると、私は自分のすべての友達を返すでしょう。通常、私はSQLでこれを行うときに私はそれらを結合するビューを使用します。 – JED

+0

EF/MVCチュートリアル(http://www.asp.net/mvc/overview/models-(data))をご覧ください。 – RickAndMSFT

答えて

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性質を持っていますユーザーと、すべてのユーザーを含むコレクション指定されたユーザーの友人です。 GroupJoinのため、結果には友人のいないユーザーも含まれます(この場合はFriendsコレクションは空です)。おおよそのように:

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

しかし、これはそのようなモデルで動作するEntity-Frameworkの方法ではありません。なし(

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

FriendShipsデータベースにだけ結合表のようになります。

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

とユーザとの間の多対多の関係は:あなたが実際にあなたのUserクラスのナビゲーションプロパティを持つ必要がありますFriendShipID列、UserIDおよびTheirFriends)を使用します。モデルではエンティティではなく、複合キーを作成します。 Userはあなたの唯一のエンティティです。それで、同じ結果をより簡単に達成することができます。

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

コードの行数が少なくなるだけでなく、読みやすく理解しやすくなります。 EFは、クエリがSQLに変換されたときにデータベース内の複雑な結合およびグループ化について気にします。

編集

あなたは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 
} 

「;ジョン、ダイアナジム」とそれらの名前 `している、これはのように、セパレータをコレクションのようなものを表しTheirFriends`文字列は`ことを意味してい

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

+0

@ JED:テーブルには、キーを一緒に構築する2つの列(UserIDとTheirFriends)しかありません。 – Slauma

+0

非常にありがとうございます。あなたの2番目の提案作業は、細かい – JED

関連する問題