LINQ to SQL:左连接多个列

首先,我搜索了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 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 = pX, Y = pY, 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 = xX, Y = xY, Titlu = x.Titlu, Descriere = x.Descriere, Public = x.Public, Votes = x.Votes, DateCreated = x.DateCreated, DateOccured = x.DateOccured, UserVoted = x.UserVoted }).AsQueryable(); 

在您的查询中,您没有进行任何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 = pX, Y = pY, 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 */ } 

如果您的问题是为多个连接条件分配关键字:

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

您必须使用.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 = pX, Y = pY, 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;