您可以使用以下方法:
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
列,UserID
和TheirFriends
改为创建一个组合键),而不是模型中的实体。 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
}
这是否意味着TheirFriends'表示类似的隔膜集合,如字符串'“吉姆,约翰,戴安娜”,这些名称是' UserIDs'?那么FriendShip类中的'UserID'属性是什么? – Slauma 2012-03-10 15:01:16
@slauma当一个用户添加一个朋友时,他会在FriendsFriend列中插入他的朋友的userID,并在友谊表中的UserID中插入他自己的用户ID。所以无论何时我在友谊表中搜索具有UserID的特定用户,我都会返回所有他或她的朋友。通常,当我在SQL中这样做时,我使用视图来加入它们。 – JED 2012-03-10 15:15:39
您应该阅读EF/MVC教程(http://www.asp.net/mvc/overview/models-(data)),其中介绍了如何实现此目的以及更多。 – RickAndMSFT 2012-03-11 18:36:10