首先,我搜索了google / SO,检查了一些示例,但我没有设法编写正确的linq表达式:
这是我的工作sql查询的样子:
select *
from Places p
left join VoteLog v
on p.Id = v.PlaceId
and v.UserId = '076a11b9-6b14-4230-99fe-28aab078cefb' --demo userid
这是我对linq的尝试:
public IQueryable<Place> GetAllPublic(string userId)
{
var result = (from p in _db.Places
join v in _db.VoteLogs
on p.Id equals v.PlaceId // This works but doesn't fully reproduce my SQL query
// on new { p.Id, userId} equals new {v.PlaceId, v.UserId} -> Not ok
where p.Public == 1
select new
{
Id = p.Id,
UserId = p.UserId,
X = p.X,
Y = p.Y,
Titlu = p.Titlu,
Descriere = p.Descriere,
Public = p.Public,
Votes = p.Votes,
DateCreated = p.DateCreated,
DateOccured = p.DateOccured,
UserVoted = v.Vote
})
.ToList()
.Select(x => new Place()
{
Id = x.Id,
UserId = x.UserId,
X = x.X,
Y = x.Y,
Titlu = x.Titlu,
Descriere = x.Descriere,
Public = x.Public,
Votes = x.Votes,
DateCreated = x.DateCreated,
DateOccured = x.DateOccured,
UserVoted = x.UserVoted
}).AsQueryable();
答案 0 :(得分:7)
在您的查询中,您没有执行任何left join
。
试试这个:
from p in _db.places
join v in _db.VoteLogs
//This is how you join by multiple values
on new { Id = p.Id, UserID = userId } equals new { Id = v.PlaceId, UserID = v.UserID }
into jointData
//This is how you actually turn the join into a left-join
from jointRecord in jointData.DefaultIfEmpty()
where p.Public == 1
select new
{
Id = p.Id,
UserId = p.UserId,
X = p.X,
Y = p.Y,
Titlu = p.Titlu,
Descriere = p.Descriere,
Public = p.Public,
Votes = p.Votes,
DateCreated = p.DateCreated,
DateOccured = p.DateOccured,
UserVoted = jointRecord.Vote
/* The row above will fail with a null reference if there is no record due to the left join. Do one of these:
UserVoted = jointRecord ?.Vote - will give the default behavior for the type of Uservoted
UserVoted = jointRecord == null ? string.Empty : jointRecord.Vote */
}
答案 1 :(得分:1)
您必须使用.DefaultIfEmpty()
执行左连接。然后,您需要决定在正确的表生成null时要执行的操作。您可以使用三元运算符( ? : )
。
var result =
(from p in _db.Places
join v in _db.VoteLogs
on new { p.Id, userId } equals new { v.PlaceId, v.UserId } into LEFTJOIN
from result in LEFTJOIN.DefaultIfEmpty()
where p.Public == 1
select new
{
Id = p.Id,
UserId = p.UserId,
X = p.X,
Y = p.Y,
Titlu = p.Titlu,
Descriere = p.Descriere,
Public = p.Public,
Votes = p.Votes,
DateCreated = p.DateCreated,
DateOccured = p.DateOccured,
UserVoted = result == null ? null /* replace with your value */ : x.Vote
}).AsQueryable();
return result;
答案 2 :(得分:1)
如果您的问题是为多个加入条件分配关键字:
// on new { p.Id, userId} equals new {v.PlaceId, v.UserId}
尝试
on new { a = p.Id, b = userId} equals new { a = v.PlaceId, b = v.UserId}