MongoDb抽象集合和向下转发

时间:2016-04-26 15:44:12

标签: c# mongodb downcast

我在MongoDb中有一个集合,其中包含派生自“FeedItemBase”类的对象。当我查询这个集合时,我返回一个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);
    }
}

有人可以帮我吗?或者告诉我是否有更好的方法。

提前致谢

1 个答案:

答案 0 :(得分:0)

Quantic指出的解决方案是在列表中投射每个项目而不是试图投射整个集合:

var commentItems = feedItems
    .Where(x => x.ObjectType == "FeedItemComment")
    .Select(x => (Models.DTO.Feed.FeedItemComment)x);

感谢Quantic