MongoDb 抽象集合和向下转型
MongoDb abstract collection and downcasting
我在 MongoDb 中有一个集合,其中包含派生自 class "FeedItemBase" 的对象。当我查询这个集合时,我 return 一个 FeedItemBase 对象的列表。
//This is my collection property in the RepoBase abstract
public IMongoCollection<T> Collection { get; set; }
//This is what my repo looks like, therefore my Collection is T = UserFeed
public class UserFeedsRepo : RepoBase<UserFeed>, IAsyncRepo<UserFeed>
{...The method below lives in this repo...}
public async Task<IEnumerable<FeedItemBase>> GetFeedItems(string userId, int skip, int limit)
{
try
{
var results = await Collection
.Aggregate()
.Match(x => x.User.Id == userId)
.Unwind<UserFeed, UnwindedFeedItems>(x => x.Items)
.SortByDescending(x => x.Items.DatePosted)
.Skip(skip)
.Limit(limit)
.ToListAsync()
.ConfigureAwait(false);
return results.Select(x => x.Items);
}
catch (Exception ex)
{
throw new Exception("An exception occured in GetFeedItems", ex);
}
}
很好。如果我将这些对象以这种形式 (DTO) 从 WebApi 作为 Json 传递给我的客户端,它们会在客户端使用 $type.
正确地序列化为它们的派生形式。
但是,有时我需要将这些 DTos 注入某些 ViewModel,以便以最简单的形式传递未保存在我的数据库中的信息:
FeedItemImage derives from FeedItemBase
FeedItemComment derives from FeedItemBase
两个对象之间的唯一区别分别是 "ImageUrl" 和 "Comment"。
我在将 FeedItemBase 对象集合转换为它们的具体形式时遇到问题,我似乎想不出一个干净的方法来解决它。我需要它们的具体形式,以便在注入到 ViewModel 构造函数时,我可以访问 Comment 和 ImageUrl 属性。
private async Task<List<FeedItemViewModelBase>> GetFeedItemViewModels(IEnumerable<Models.DTO.Feed.FeedItemBase> feedItems)
{
try
{
List<FeedItemViewModelBase> viewModels = new List<FeedItemViewModelBase>();
//This is where it is currently bombing out
var commentItems = (IEnumerable<Models.DTO.Feed.FeedItemComment>)feedItems.Where(x => x.ObjectType == "FeedItemComment");
var imageItems = (IEnumerable<Models.DTO.Feed.FeedItemImage>)feedItems.Where(x => x.ObjectType == "FeedItemImage");
//These 2 lines return populate view models to be added to the list to be returned
var commentViewModelsTask = GetFeedItemCommentViewModels(commentItems).ConfigureAwait(false);
var imageViewModelsTask = GetFeedItemImageViewModels(imageItems).ConfigureAwait(false);
viewModels.AddRange(await commentViewModelsTask);
viewModels.AddRange(await imageViewModelsTask);
return viewModels;
}
catch (Exception ex)
{
throw new Exception("There was a problem retrieving feed item viewmodels", ex);
}
}
有人可以帮我解决这个问题吗?或者告诉我是否有更好的方法。
提前致谢
Quantic 指出的解决方案是投射列表中的每一项,而不是试图投射整个集合:
var commentItems = feedItems
.Where(x => x.ObjectType == "FeedItemComment")
.Select(x => (Models.DTO.Feed.FeedItemComment)x);
感谢 Quantic
我在 MongoDb 中有一个集合,其中包含派生自 class "FeedItemBase" 的对象。当我查询这个集合时,我 return 一个 FeedItemBase 对象的列表。
//This is my collection property in the RepoBase abstract
public IMongoCollection<T> Collection { get; set; }
//This is what my repo looks like, therefore my Collection is T = UserFeed
public class UserFeedsRepo : RepoBase<UserFeed>, IAsyncRepo<UserFeed>
{...The method below lives in this repo...}
public async Task<IEnumerable<FeedItemBase>> GetFeedItems(string userId, int skip, int limit)
{
try
{
var results = await Collection
.Aggregate()
.Match(x => x.User.Id == userId)
.Unwind<UserFeed, UnwindedFeedItems>(x => x.Items)
.SortByDescending(x => x.Items.DatePosted)
.Skip(skip)
.Limit(limit)
.ToListAsync()
.ConfigureAwait(false);
return results.Select(x => x.Items);
}
catch (Exception ex)
{
throw new Exception("An exception occured in GetFeedItems", ex);
}
}
很好。如果我将这些对象以这种形式 (DTO) 从 WebApi 作为 Json 传递给我的客户端,它们会在客户端使用 $type.
正确地序列化为它们的派生形式。但是,有时我需要将这些 DTos 注入某些 ViewModel,以便以最简单的形式传递未保存在我的数据库中的信息:
FeedItemImage derives from FeedItemBase
FeedItemComment derives from FeedItemBase
两个对象之间的唯一区别分别是 "ImageUrl" 和 "Comment"。
我在将 FeedItemBase 对象集合转换为它们的具体形式时遇到问题,我似乎想不出一个干净的方法来解决它。我需要它们的具体形式,以便在注入到 ViewModel 构造函数时,我可以访问 Comment 和 ImageUrl 属性。
private async Task<List<FeedItemViewModelBase>> GetFeedItemViewModels(IEnumerable<Models.DTO.Feed.FeedItemBase> feedItems)
{
try
{
List<FeedItemViewModelBase> viewModels = new List<FeedItemViewModelBase>();
//This is where it is currently bombing out
var commentItems = (IEnumerable<Models.DTO.Feed.FeedItemComment>)feedItems.Where(x => x.ObjectType == "FeedItemComment");
var imageItems = (IEnumerable<Models.DTO.Feed.FeedItemImage>)feedItems.Where(x => x.ObjectType == "FeedItemImage");
//These 2 lines return populate view models to be added to the list to be returned
var commentViewModelsTask = GetFeedItemCommentViewModels(commentItems).ConfigureAwait(false);
var imageViewModelsTask = GetFeedItemImageViewModels(imageItems).ConfigureAwait(false);
viewModels.AddRange(await commentViewModelsTask);
viewModels.AddRange(await imageViewModelsTask);
return viewModels;
}
catch (Exception ex)
{
throw new Exception("There was a problem retrieving feed item viewmodels", ex);
}
}
有人可以帮我解决这个问题吗?或者告诉我是否有更好的方法。
提前致谢
Quantic 指出的解决方案是投射列表中的每一项,而不是试图投射整个集合:
var commentItems = feedItems
.Where(x => x.ObjectType == "FeedItemComment")
.Select(x => (Models.DTO.Feed.FeedItemComment)x);
感谢 Quantic