Как объединить две таблицы в коде первым подходом - PullRequest
0 голосов
/ 10 марта 2012

У меня две таблицы, Пользователь и Дружба.Я хочу объединить эти две таблицы, чтобы столбец «Их друзья», которые имеют идентификатор пользователя всех друзей, имел атрибут «Пользователь».то есть я хочу получить каждого друга со всеми их атрибутами.Выходные данные будут выглядеть следующим образом. Их имя и фамилия Фамилия Имя пользователя

Мне нужно это выражение linq и лямбда.

Пользователь:

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

FriendShip

 public class FriendShip
{

    public int FriendShipID { get; set; }
    public string TheirFriends { get; set; }

    public String UserID { get; set; }
}

1 Ответ

3 голосов
/ 10 марта 2012

Вы можете использовать следующее:

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"

Но это не способ Entity-Framework для работы с такой моделью.На самом деле у вас должно быть свойство навигации в вашем 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();

Не только меньше строк кода, но и намного проще для чтения и понимания.EF позаботится о сложном объединении и группировке в базе данных при переводе запроса в SQL.

Edit

Вы можете добавить отношения (= строки в таблице ссылок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
}
...