2016-04-26 4 views
0

У меня есть коллекция в MongoDb, которая содержит объекты, которые получены из класса «FeedItemBase». Когда я запрашиваю эту коллекцию, я возвращаю список объектов FeedItemBase.MongoDb абстрактная коллекция и downcasting

//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 в некоторые ViewModels для того, чтобы передать информацию, которая не сохраняется в моей базе данных, в их простейших формах:

FeedItemImage derives from FeedItemBase 
FeedItemComment derives from FeedItemBase 

только различались 2 объекта - «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

Я думаю, что проблема заключается в том, что вам нужно отбрасывать каждый объект в списке отдельно. Вы не можете использовать 'List ' '' List ', вы должны' foreach (b в listOfBaseObjects) {newList.Add ((b как производный));} '. – Quantic

+0

Doh! Спасибо Quantic, вы правы. Я использовал linq для создания каждого элемента. Указано в обновлении вопроса. – pieperu

+0

Вы можете опубликовать ответ в реальном ответе вместо редактирования. На самом деле, я думаю, они предпочитают это. – Quantic

ответ

0

решение, как Quantic указывал было отливать каждый элемент в списке, а не пытаться бросить всю коллекцию:

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

Благодаря Quantic

Смежные вопросы