这个左外连接查询的正确 Linq 表达式是什么?
What is the proper Linq expression for this left-outer-join query?
我无法将他的 sql 查询转换为 returns 结果作为 class 的 IEnumerable 的 linq 表达式。
这是查询:
Select * from Posts left outer join Ownergroups on
Posts.PostId=Ownergroups.PostID
Where Ownergroups.OwnerName = 'Group A' AND PostType = 'news'
这是唯一不会引发错误的表达式,但它也只有 returns 一个结果。
NewsViewModel vm = new NewsViewModel();
vm.NewsItems = (from an in db.Posts.Where(g => g.PostType == "News")
from og in an.OwnerGroups.Where(g => g.OwnerName == "Group A")
select an).Distinct().OrderByDescending(bb
=>bb.PostDate).ToList();
如果我尝试投影到新选择,我会收到错误消息。当我尝试按 PostId 分组时,我得到了正确的结果,但无法将结果附加到我的 ViewModel;我收到一条错误消息 "cannot convert type systems.collections.generic list to systems.collections.IEnumerable"
非常感谢您的建议。
根据要求添加 class:
public class Post
{
public int PostId { get; set; }
public string PostType { get; set; }
[Display(Name = "Top Title")]
[MaxLength(300)]
public string Headline1 { get; set; }
[Display(Name = "Subtitle")]
[MaxLength(300)]
public string Headline2 { get; set; }
public string Headline3 { get; set; }
[Display(Name = "By Organization or Person")]
[MaxLength(250)]
public string Byline { get; set; }
[Display(Name = "Text For Your Post")]
[MaxLength(4999)]
[AllowHtml]
public string PostText1 { get; set; }
[Display(Name = "Additional Text")]
[MaxLength(4999)]
[AllowHtml]
public string PostText2 { get; set; }
public string AuthorGroup { get; set; }
[Display(Name = "Link to Video (URL)")]
[MaxLength(249)]
public string AVurl { get; set; }
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:d}")]
public DateTime PostDate { get; set; }
[Display(Name = "Date To Archive")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:d}")]
public DateTime? StopDate { get; set; }
[Display(Name = "Posted By")]
public string PostedBy { get; set; }
[Display(Name = "Last Edited")]
public DateTime LastEditDate { get; set; }
[Display(Name = "Last Edited By")]
public string LastEditor { get; set; }
public virtual ICollection<PostAsset> PostAssets { get; set; }
public virtual ICollection<PostAlbum> PostAlbums { get; set; }
public virtual ICollection<OwnerGroup> OwnerGroups { get; set; }
以下将在所有者 OwnerName = 'Group A'
和 PostType = 'news'
加入的情况下进行左联接,如果可能的话,在 PostId = PostId
void Main()
{
var posts =
new List<Post>()
{
new Post {PostId = 1, PostType = "news"},
new Post {PostId = 2, PostType = "old"},
new Post {PostId = 3, PostType = "news"},
};
var owners =
new List<OwnerGroup>()
{
new OwnerGroup {GroupId = 1, PostId = 1, OwnerName = "Group A" },
new OwnerGroup {GroupId = 2, PostId = 1, OwnerName = "Group A" },
new OwnerGroup {GroupId = 3, PostId = 2, OwnerName = "Group A" },
};
var leftJoinResult = posts
.GroupJoin(
owners.Where(o => o.OwnerName.Equals("Group A")),
r => r.PostId, rp => rp.PostId,
(l1, l2) => new { gjl1 = l1, gjl2 = l2 })
.SelectMany(x => x.gjl2.DefaultIfEmpty(), (x, gjl2) => new { x.gjl1, gjl2 })
.Where(x => x.gjl1.PostType.Equals("news") )
// OPTIONAL: Add this line return the Post matches, not both the Post and the possible left joined OwnerGroup
.Select(x => x.gjl1)
// OPTIONAL: Add this line to only get the distinct Post matches
.GroupBy(p => p.PostId).Select(grp => grp.First());
}
public class Post
{
public int PostId { get; set; }
public string PostType { get; set; }
}
public class OwnerGroup
{
public int GroupId { get;set; }
public int PostId { get; set; }
public String OwnerName { get; set; }
}
我无法将他的 sql 查询转换为 returns 结果作为 class 的 IEnumerable 的 linq 表达式。
这是查询:
Select * from Posts left outer join Ownergroups on
Posts.PostId=Ownergroups.PostID
Where Ownergroups.OwnerName = 'Group A' AND PostType = 'news'
这是唯一不会引发错误的表达式,但它也只有 returns 一个结果。
NewsViewModel vm = new NewsViewModel();
vm.NewsItems = (from an in db.Posts.Where(g => g.PostType == "News")
from og in an.OwnerGroups.Where(g => g.OwnerName == "Group A")
select an).Distinct().OrderByDescending(bb
=>bb.PostDate).ToList();
如果我尝试投影到新选择,我会收到错误消息。当我尝试按 PostId 分组时,我得到了正确的结果,但无法将结果附加到我的 ViewModel;我收到一条错误消息 "cannot convert type systems.collections.generic list to systems.collections.IEnumerable"
非常感谢您的建议。
根据要求添加 class:
public class Post
{
public int PostId { get; set; }
public string PostType { get; set; }
[Display(Name = "Top Title")]
[MaxLength(300)]
public string Headline1 { get; set; }
[Display(Name = "Subtitle")]
[MaxLength(300)]
public string Headline2 { get; set; }
public string Headline3 { get; set; }
[Display(Name = "By Organization or Person")]
[MaxLength(250)]
public string Byline { get; set; }
[Display(Name = "Text For Your Post")]
[MaxLength(4999)]
[AllowHtml]
public string PostText1 { get; set; }
[Display(Name = "Additional Text")]
[MaxLength(4999)]
[AllowHtml]
public string PostText2 { get; set; }
public string AuthorGroup { get; set; }
[Display(Name = "Link to Video (URL)")]
[MaxLength(249)]
public string AVurl { get; set; }
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:d}")]
public DateTime PostDate { get; set; }
[Display(Name = "Date To Archive")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:d}")]
public DateTime? StopDate { get; set; }
[Display(Name = "Posted By")]
public string PostedBy { get; set; }
[Display(Name = "Last Edited")]
public DateTime LastEditDate { get; set; }
[Display(Name = "Last Edited By")]
public string LastEditor { get; set; }
public virtual ICollection<PostAsset> PostAssets { get; set; }
public virtual ICollection<PostAlbum> PostAlbums { get; set; }
public virtual ICollection<OwnerGroup> OwnerGroups { get; set; }
以下将在所有者 OwnerName = 'Group A'
和 PostType = 'news'
加入的情况下进行左联接,如果可能的话,在 PostId = PostId
void Main()
{
var posts =
new List<Post>()
{
new Post {PostId = 1, PostType = "news"},
new Post {PostId = 2, PostType = "old"},
new Post {PostId = 3, PostType = "news"},
};
var owners =
new List<OwnerGroup>()
{
new OwnerGroup {GroupId = 1, PostId = 1, OwnerName = "Group A" },
new OwnerGroup {GroupId = 2, PostId = 1, OwnerName = "Group A" },
new OwnerGroup {GroupId = 3, PostId = 2, OwnerName = "Group A" },
};
var leftJoinResult = posts
.GroupJoin(
owners.Where(o => o.OwnerName.Equals("Group A")),
r => r.PostId, rp => rp.PostId,
(l1, l2) => new { gjl1 = l1, gjl2 = l2 })
.SelectMany(x => x.gjl2.DefaultIfEmpty(), (x, gjl2) => new { x.gjl1, gjl2 })
.Where(x => x.gjl1.PostType.Equals("news") )
// OPTIONAL: Add this line return the Post matches, not both the Post and the possible left joined OwnerGroup
.Select(x => x.gjl1)
// OPTIONAL: Add this line to only get the distinct Post matches
.GroupBy(p => p.PostId).Select(grp => grp.First());
}
public class Post
{
public int PostId { get; set; }
public string PostType { get; set; }
}
public class OwnerGroup
{
public int GroupId { get;set; }
public int PostId { get; set; }
public String OwnerName { get; set; }
}