我有两个表,用户和友谊。我想加入这两个表,以便具有所有朋友的UserID的列OurFriends将具有User中的一些属性。那就是我想让每个朋友都拥有他们所有的属性。 输出将如下所示 他们的朋友名字姓LastName UserPicture
我需要这个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 :(得分: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
列,UserID
和TheirFriends
而是构建一个复合键)而不是您的实体模型。 User
是您唯一的实体。然后你可以更轻松地实现相同的结果:
var usersWithFriends = context.Users.Include(u => u.Friends).ToList();
不仅更少的代码行,而且更容易阅读和理解。当查询转换为SQL时,EF将关心数据库中的复杂连接和分组。
修改强>
您可以通过将现有用户添加到FriendShips
集合来添加关系(=链接表Friends
中的行):
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
}
由于您拥有主键值,因此也可以不从数据库中查询用户:
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
}