使用 Linq 左连接多个 IList<>
Left join multiple IList<> using Linq
我基本上有一个 post 存储库,应该 return 所有画廊项目都属于它。如果没有属于 post 的画廊,它应该仍然 return post 与 post id
不同
public List<PostLocalizedOutput> GetAllPostsWithCategories(string culture, bool? isPublished)
{
var query =
from p in Context.Posts
join pl in Context.PostsLocalized on p.Id equals pl.PostId
from c in p.Categories
join cl in Context.CategoriesLocalized on c.Id equals cl.CategoryId
from g in p.Galleries.DefaultIfEmpty()
join gi in Context.GalleryItems on g.Id equals gi.GalleryId
where
pl.Culture == culture &&
cl.Culture == culture
select new PostLocalizedOutput
{
PostId = pl.PostId,
CategoryId = cl.CategoryId,
Title = pl.Title,
FormattedCategoryName = cl.FormattedCategoryName,
PostContent = pl.PostContent,
PostType = pl.Post.PostType,
IOrder = pl.Post.IOrder,
Tags = pl.Tags,
PublishDate = pl.Post.PublishDate,
ViewCount = pl.Post.ViewCount,
ShowInHomePageSlider = pl.Post.ShowInHomePageSlider,
AllowComments = pl.Post.AllowComments,
Image = pl.Post.Image,
IsArchived = pl.Post.IsArchived,
IsDraft = pl.Post.IsDraft,
IsPublished = pl.Post.IsPublished,
GalleryItems = new GalleryItemOutput
{
FileName = gi.FileName,
GalleryId = gi.GalleryId,
Id = gi.Id,
Notes = gi.Notes,
Title = gi.Title
} (around here i feel like i should foreach something or what?)
};
return query.OrderBy(x => x.IOrder).ThenBy(x => x.PublishDate).DistinctBy(x => x.PostId).ToList();
}
这是我的 postlocalizedoutput
public class PostLocalizedOutput : IOutputDto
{
public int PostId { get; set; }
public int CategoryId { get; set; }
public bool IsPublished { get; set; }
...
public List<GalleryItemOutput> GalleryItems { get; set; }
}
GalleryItemOutput 应该是列表,因为我想要 post 的所有画廊项目。但是当我将它定义为存储库中的列表时,我无法设置 post 的 galleryitem 的每个字段。这段代码现在 return 我有四行,因为我有四个画廊项目 post 并且每个都有相同的 postId。我不要那个。 DefaultIfEmpty 也不起作用,即使 post 没有任何画廊项目我应该仍然能够在没有画廊项目的情况下获得 post。
有什么方法吗?
感谢所有建议。
这应该可以帮助您入门。
不知道这是否编译,请只解释为伪代码。看起来您的顶级范围变量是 PostsLocalized 而不是 Posts。此代码 assume/uses 导航属性可能已在您的 EDM 类 中设置。我在这里过度使用 let 关键字只是为了让你更清楚。在 select 新子句中,您可以将 p1.Post... 更改为仅 p。我让他们尽可能少地进行编辑。
var query =
from pl in Context.PostsLocalized
where pl.Culture == culture
let p = p1.Post
let categories = p.Categories
let localizedCategories = categories.SelectMany(cat => cat.CategoriesLocalized).Where(cl => cl.Culture == culture)
let galleries = p.Galleries
let galleryItems = galleries.SelectMany(gal => gal.GalleryItems)
let cl = localizedCategories.FirstOrDefault() // only one or zero of these i assume?
select new PostLocalizedOutput
{
PostId = p1.PostId,
CategoryId = cl.CategoryId,
Title = pl.Title,
FormattedCategoryName = cl.FormattedCategoryName,
PostContent = pl.PostContent,
PostType = pl.Post.PostType,
IOrder = pl.Post.IOrder,
Tags = pl.Tags,
PublishDate = pl.Post.PublishDate,
ViewCount = pl.Post.ViewCount,
ShowInHomePageSlider = pl.Post.ShowInHomePageSlider,
AllowComments = pl.Post.AllowComments,
Image = pl.Post.Image,
IsArchived = pl.Post.IsArchived,
IsDraft = pl.Post.IsDraft,
IsPublished = pl.Post.IsPublished,
GalleryItems = galleryItems.Select(gi => new GalleryItemOutput
{
FileName = gi.FileName,
GalleryId = gi.GalleryId,
Id = gi.Id,
Notes = gi.Notes,
Title = gi.Title
})
// might need a .ToList() here on those GalleryItems
(around here i feel like i should foreach something or what?)
};
我基本上有一个 post 存储库,应该 return 所有画廊项目都属于它。如果没有属于 post 的画廊,它应该仍然 return post 与 post id
不同public List<PostLocalizedOutput> GetAllPostsWithCategories(string culture, bool? isPublished)
{
var query =
from p in Context.Posts
join pl in Context.PostsLocalized on p.Id equals pl.PostId
from c in p.Categories
join cl in Context.CategoriesLocalized on c.Id equals cl.CategoryId
from g in p.Galleries.DefaultIfEmpty()
join gi in Context.GalleryItems on g.Id equals gi.GalleryId
where
pl.Culture == culture &&
cl.Culture == culture
select new PostLocalizedOutput
{
PostId = pl.PostId,
CategoryId = cl.CategoryId,
Title = pl.Title,
FormattedCategoryName = cl.FormattedCategoryName,
PostContent = pl.PostContent,
PostType = pl.Post.PostType,
IOrder = pl.Post.IOrder,
Tags = pl.Tags,
PublishDate = pl.Post.PublishDate,
ViewCount = pl.Post.ViewCount,
ShowInHomePageSlider = pl.Post.ShowInHomePageSlider,
AllowComments = pl.Post.AllowComments,
Image = pl.Post.Image,
IsArchived = pl.Post.IsArchived,
IsDraft = pl.Post.IsDraft,
IsPublished = pl.Post.IsPublished,
GalleryItems = new GalleryItemOutput
{
FileName = gi.FileName,
GalleryId = gi.GalleryId,
Id = gi.Id,
Notes = gi.Notes,
Title = gi.Title
} (around here i feel like i should foreach something or what?)
};
return query.OrderBy(x => x.IOrder).ThenBy(x => x.PublishDate).DistinctBy(x => x.PostId).ToList();
}
这是我的 postlocalizedoutput
public class PostLocalizedOutput : IOutputDto
{
public int PostId { get; set; }
public int CategoryId { get; set; }
public bool IsPublished { get; set; }
...
public List<GalleryItemOutput> GalleryItems { get; set; }
}
GalleryItemOutput 应该是列表,因为我想要 post 的所有画廊项目。但是当我将它定义为存储库中的列表时,我无法设置 post 的 galleryitem 的每个字段。这段代码现在 return 我有四行,因为我有四个画廊项目 post 并且每个都有相同的 postId。我不要那个。 DefaultIfEmpty 也不起作用,即使 post 没有任何画廊项目我应该仍然能够在没有画廊项目的情况下获得 post。
有什么方法吗?
感谢所有建议。
这应该可以帮助您入门。 不知道这是否编译,请只解释为伪代码。看起来您的顶级范围变量是 PostsLocalized 而不是 Posts。此代码 assume/uses 导航属性可能已在您的 EDM 类 中设置。我在这里过度使用 let 关键字只是为了让你更清楚。在 select 新子句中,您可以将 p1.Post... 更改为仅 p。我让他们尽可能少地进行编辑。
var query =
from pl in Context.PostsLocalized
where pl.Culture == culture
let p = p1.Post
let categories = p.Categories
let localizedCategories = categories.SelectMany(cat => cat.CategoriesLocalized).Where(cl => cl.Culture == culture)
let galleries = p.Galleries
let galleryItems = galleries.SelectMany(gal => gal.GalleryItems)
let cl = localizedCategories.FirstOrDefault() // only one or zero of these i assume?
select new PostLocalizedOutput
{
PostId = p1.PostId,
CategoryId = cl.CategoryId,
Title = pl.Title,
FormattedCategoryName = cl.FormattedCategoryName,
PostContent = pl.PostContent,
PostType = pl.Post.PostType,
IOrder = pl.Post.IOrder,
Tags = pl.Tags,
PublishDate = pl.Post.PublishDate,
ViewCount = pl.Post.ViewCount,
ShowInHomePageSlider = pl.Post.ShowInHomePageSlider,
AllowComments = pl.Post.AllowComments,
Image = pl.Post.Image,
IsArchived = pl.Post.IsArchived,
IsDraft = pl.Post.IsDraft,
IsPublished = pl.Post.IsPublished,
GalleryItems = galleryItems.Select(gi => new GalleryItemOutput
{
FileName = gi.FileName,
GalleryId = gi.GalleryId,
Id = gi.Id,
Notes = gi.Notes,
Title = gi.Title
})
// might need a .ToList() here on those GalleryItems
(around here i feel like i should foreach something or what?)
};