Как получить все столбцы из таблицы 1 и сопоставить столбцы из таблицы2 (левое внешнее соединение) с помощью Linq

Мне нужно получить все столбцы из таблицы1 и сопоставить столбцы из таблицы2. У меня есть хранимая процедура:

alter  Procedure [dbo].[usp_Property]
@UserId bigint =null
As
Begin
select P.PID, P.PropertyName, P.SBUArea, P.ListedOn, 
       P.Availability, P.Price,   F.UserID, F.PID as FavProjId  
       from dbo.Property P left outer join dbo.Favorite F
       on (F.PID=P.PID And [email protected])

Я хочу получить запрос Linq для того же самого. До сих пор я пытался с чем-то вроде

//User Id comes from session..
//var userId
var result=(from p in Properties
                   join f in Favorites
                   on p.PID equals f.PID into r
                   from r1 in r.DefaultIfEmpty()
                   where r1.UserID==userId
                   select new
                   {
                     p.PID,
                      p.PropertyName,                       
                      p.SBUArea, p.ListedOn,
                      r1.UserId
                   });

Кто-нибудь может меня поправить. Я хочу использовать левое внешнее соединение или любую другую альтернативную вещь здесь.

Ответ 1

Если я украшу ваш код SP, я получаю следующее:

DECLARE @UserId int 
SET @UserId = 12435 

SELECT 
     P.PID
    ,P.PropertyName
    ,P.SBUArea
    ,P.ListedOn 
    ,P.Availability
    ,P.Price
    ,F.UserID
    ,F.PID AS FavProjId  
FROM Property AS P 
LEFT JOIN Favorite AS F
    ON (F.PID=P.PID AND F.UserID = @UserId)

Теперь мне интересно, нужен ли вам этот UserId в предложении WHERE SQL или действительно в соединении.

Но в любом случае здесь LINQ-эквивалент именно того SQL:

System.Int64 __UserId = 12435;

var query = (
    from P in Repo.Property
    from F in Repo.Favorite
         .Where(fav=> fav.PID == P.PID && fav.UserID == __UserId)
         .DefaultIfEmpty() // <== makes join left join
    select new
    {
         PID = P.PID
        ,PropertyName = P.PropertyName
        ,SBUArea = P.SBUArea
        ,ListenOn = P.ListedOn 
        ,Availabiity = P.Availability
        ,Price = P.Price
        ,UserId = F.UserID
        ,FavProjId = F.PID 
    }

);

var data = (query).ToList();

Ответ 2

Если вы поместите предложение where после join, вы можете получить исключение ссылочной ссылки, потому что DefaultIfEmpty возвращает значение по умолчанию для несоответствующих строк. Вы можете фильтровать записи, прежде чем присоединяться к ним следующим образом: -

var result=(from p in Properties
            join f in Favorites.Where(x => x.UserID == userId)
            on p.PID equals f.PID into r
            from r1 in r.DefaultIfEmpty()
            select new
            {
                p.PID,
                p.PropertyName,                       
                p.SBUArea, 
                p.ListedOn,
                r1.UserId
            });

Обратите внимание, что вам нужно получить доступ к свойствам Favorites с помощью r1.

Update:

Насколько я понял, вам нужны все записи из таблицы Property и только соответствующие строки из таблицы Favorite. Но у вас есть фильтр на вашей любимой таблице, поэтому конечный источник данных будет отличаться. Позвольте мне пояснить этот пример: -

Предположим, что у вас есть следующие данные в таблице Property: -

PID    PropertyName    Availability    Price
 1          aaa            true         20
 2          bbb            false        10
 3          ccc            true         50
 4          ddd            false        80
 5          eee            true         55
 6          fff            false        70

и Favorite таблица выглядит следующим образом: -

FID    PID    UserId
 1      4      1001
 2      2      1005
 3      5      1007

И позвольте сказать, что вам нужны все записи для UserId 1005, тогда результат должен содержать все идентификатор свойства от 1 до 6, даже если UserId 1005 не подходит для свойств Id 4 и 2 правильно? Таким образом, указанный выше запрос соответствует этому пониманию. Проверьте этот Fiddle с помощью того же примера и вывода.

Ответ 3

Использование анонимных объектов в вашем выборе

var result = from t in table1
             join x in table2
             on t.id equals x.id
             select new { id = t.id, col1 = t.col1, col2 = x.col2 }