2016-04-26 6 views
0

私はMongoDbに "FeedItemBase"クラスから派生したオブジェクトを含むコレクションを持っています。このコレクションにクエリを実行すると、FeedItemBaseオブジェクトのリストが返されます。MongoDb抽象コレクションとダウンキャスト

//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)のオブジェクトをJsonとしてWebApiからクライアントに渡すと、クライアントは$ typeを使用して派生フォームに正しくシリアル化されます。

FeedItemImage derives from FeedItemBase 
FeedItemComment derives from FeedItemBase 

の間でのみ異なる:

しかし、私は彼らの最も単純な形で、私のデータベースに保存されていない情報を伝承するために、いくつかのviewmodelsにこれらのDTOを注入する必要があるポイントがあります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(listOfBaseObjects内のb){newList.Add((b as derived))}}'する必要があります。 – Quantic

+0

Doh!ありがとうクワンティック、あなたは正しいです。私はlinqを使って各項目をキャスト - 質問の更新に表示 – pieperu

+0

あなたは実際の回答を編集する代わりに投稿することができます。実際に私は彼らがそれを好むと思う。 – Quantic

答えて

0

おかげソリューションQuanticのは、リストの各項目をキャストすることだったのではなく、コレクション全体をキャストしようとして指摘したように:

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

おかげQuanticの