【问题标题】:How to Join two table in Code first approach如何在代码优先方法中加入两个表
【发布时间】:2012-03-12 01:08:14
【问题描述】:

我有两个表,用户和友谊。我想加入这两个表,以便具有所有朋友的用户 ID 的列他们的朋友将具有用户中的某些属性。那就是我想让每个朋友都拥有他们的所有属性。 输出将如下所示 他们的朋友名字姓氏用户图片

我需要这个 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; }
}

【问题讨论】:

  • 这是否意味着字符串TheirFriends 表示类似于带有分隔符的集合,例如“Jim;John;Diana”,这些名称是UserIDs?那么FriendShip 类中的UserID 属性是什么?
  • @slauma 当用户添加好友时,会将好友的用户 ID 插入到 FriendsFriend 列中,并将他自己的用户 ID 插入到友谊表的 UserID 中。因此,每当我在 Friendship 表中使用 UserID 搜索特定用户时,我都会返回他或她的所有朋友。通常,当我在 sql 中执行此操作时,我会使用视图来加入它们。
  • 您应该阅读 EF/MVC 教程 (asp.net/mvc/overview/models-(data) ),其中展示了如何做到这一点以及更多内容。
  • @Rick.Anderson-at-Microsoft.com:您在我上方评论中的链接已损坏(URL 看起来不完整)。

标签: asp.net-mvc entity-framework c#-4.0 ef-code-first


【解决方案1】:

您可以使用以下内容:

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
}

由于您拥有主键值,因此也可以不从数据库中查询用户:

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
}

【讨论】:

  • @JED:该表将只有两列(用户 ID 和他们的朋友),它们一起构建一个键。
  • 这项工作正常,但不知道如何将数据添加到友谊表。
  • 我一切正常,但我无法将数据插入到具有 UserID 和 Thierfriends 的友谊表中。我该怎么做。谢谢
  • @JED:我添加了两个用于添加/删除关系的示例。有关更多详细信息或问题,请创建一个新问题(无需任何费用)。我们已经放弃了您最初的问题。
  • @JED - 您应该阅读 EF/MVC 教程 (asp.net/mvc/overview/models-(data) ),其中展示了如何做到这一点以及更多内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-13
  • 1970-01-01
相关资源
最近更新 更多