эквивалентный запрос общих друзей в синтаксисе linq или lambda - PullRequest
0 голосов
/ 07 июля 2019

У меня есть две таблицы tblFriends и tblUsers, в которых я храню идентификатор пользователя и идентификатор друга. Теперь я хотел бы найти общих друзей user1 и user2 в таблице 'tblFriends' И подробности о них e.q. ник, возраст ...

tblUsers:

Username  nvarchar
Avatar    nvarchar
Age       int


tblFriends:

IdUser1         nvarchar
IdUser2         nvarchar
FriendStatus    int

Я нахожу ниже решение в SQL, и оно отлично работает, но мне нужен эквивалент этого запроса в LINQ или Lambda

решение, которое я нахожу здесь (https://www.codeproject.com/Questions/280296/query-to-display-mutual-friends)

SELECT P1.Name
FROM dbo.Friendship AS F1
JOIN dbo.Person AS P1 ON P1.ID = F1.FriendID
WHERE F1.PersonID = 1 AND
      F1.FriendID IN (SELECT F2.FriendID
                      FROM dbo.Friendship AS F2
                      WHERE F2.PersonID = 2)

Ответы [ 2 ]

0 голосов
/ 07 июля 2019

Нет необходимости в Join:

var mutualFriendsNames = db.Users
    .Where(u =>
        db.FriendShips.Any(f => f.FriendId == u.Id && f.UserId == 1) &&
        db.FriendShips.Any(f => f.FriendId == u.Id && f.UserId == 2))
    .Select(p => p.Name);

Просто обратите внимание, что это будет работать только в том случае, если дружеские отношения являются односторонними отношениями (если user1 является другом с user2, то user2 не является необходимым другом с user1).

Если отношение двухстороннее, у вас есть два варианта:

  1. Определить отношение как две строки в БД (каждая описывает путь).
  2. Это неявное двустороннее отношение, поэтому вы должны рефакторинг запроса LINQ выше:
var mutualFriendsNames = db.Users
    .Where(u =>
        db.FriendShips.Any(f => 
            (f.FriendId == u.Id && f.UserId == 1) ||
            (f.FriendId == 1 && f.UserId == u.Id)) &&
        db.FriendShips.Any(f => 
            (f.FriendId == u.Id && f.UserId == 2) ||
            (f.FriendId == 2 && f.UserId == u.Id)))
    .Select(p => p.Name);
0 голосов
/ 07 июля 2019

Этот пример эквивалентен данному запросу SQL

using System;
using System.Collections.Generic;
using System.Linq;

namespace Friends
{
    class Program
    {
        static void Main(string[] args)
        {

            var data = new GenerateExampleData();
            var lstFriendId = (from f in data.lstFriend
                               where f.PersonId == 2
                               select f.FriendId
                              );

            var lstMutualFriend = (from f in data.lstFriend
                                   join p in data.lstPerson on f.FriendId equals p.Id
                        where lstFriendId.Contains(f.FriendId) && f.PersonId == 1
                        select p.Name
                       );
            foreach (var item in lstMutualFriend)
            {
                Console.WriteLine(item);
            }           
            Console.ReadLine();
        }
    }

    public class GenerateExampleData
    {
        public List<Person> lstPerson;
        public List<Friendship> lstFriend;

        public GenerateExampleData()
        {
            lstPerson = new List<Person>
            {
                new Person
                {
                    Id = 1,
                    Name ="Person1"
                },
                new Person
                {
                    Id = 2,
                    Name ="Person2"
                },
                new Person
                {
                    Id = 3,
                    Name ="Person3"
                },
                new Person
                {
                    Id = 4,
                    Name ="Person4"
                },

            };

            lstFriend = new List<Friendship>
            {
                new Friendship
                {
                    PersonId = 1,
                    FriendId = 2
                },

                new Friendship
                {
                    PersonId = 1,
                    FriendId = 4
                },

                new Friendship
                {
                    PersonId = 2,
                    FriendId = 4
                },
            };
        }

    }

    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    public class Friendship
    {
        public int PersonId { get; set; }
        public int FriendId { get; set; }
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...