Мне нужно получить все столбцы из таблицы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 F.UserID=@UserId)
Я хочу получить запрос 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 }