2015-04-18 19 views
6

Mam następującą strukturę:Projekcja MongoDB dokument podrzędny przy użyciu C sterownik # .NET 2.0

public class Category 
{ 
    [BsonElement("name")] 
    public string CategoryName { get; set; } 

    [BsonDateTimeOptions] 
    [BsonElement("dateCreated")] 
    public DateTime DateStamp { get; set; } 

    [BsonElement("tasks")]   
    public List<TaskTracker.Task> Task { get; set; } 
} 

public class Task 
{ 
    [BsonElement("name")] 
    public string TaskName { get; set; } 

    [BsonElement("body")] 
    public string TaskBody { get; set; } 
} 

Próbuję kwerendy Category aby uzyskać wszystkie wartości TaskName a następnie zwrócić je do listy mają być wyświetlane w pole listy.

Próbowałem przy użyciu tej kwerendy:

var getTasks = Categories.Find<Category>(x => x.CategoryName == catName) 
         .Project(Builders<Category>.Projection 
                .Include("tasks.name") 
                .Exclude("_id")) 
         .ToListAsync() 
         .Result; 

Ale co się zwrócony jest: {"tasks": [{"name: "test"}]}.

Czy mimo to wystarczy zwrócić wartość ciągu?

Odpowiedz

10

Jak powiedział Avish, należy użyć interfejsu API agregacji, aby uzyskać wynikowy dokument wyglądający tak, jak chcesz. Jednak sterownik może sprawić, że niektóre z nich znikną, jeśli użyjesz API drzewa wyrażeń dla projektu, tak jak zrobiłeś to dla Find. Na przykład, wierzę dodaje powinny pracować dla Ciebie:

var taskNames = await Categores.Find(x => x.CategoryName == catName) 
    .Project(x => x.Tasks.Select(y => y.Name)) 
    .ToListAsync(); 

ten powinien po prostu przywrócić jest przeliczalny ciągów (tasks.name) dla każdej kategorii. Sterownik będzie sprawdzać tę projekcję i tylko cofnąć pole tasks.name.

+0

Próbowałem Twojego zapytania i próbowałem dodać go do 'Listy >' ale to, co jest zwracane, to: '{System.Linq.Enumerable.WhereSelectEnumerableIterator } ' – Lynchy

+0

Tak, to jest zamienny na IEnumerable . Czy możesz podać więcej kodu o tym, co robisz? –

+0

Myślę, że znalazłem rozwiązanie. Zwróciłem zapytanie 'taskNames' w następujący sposób:' return taskNames [0] .ToList(); 'i wydawało się, że to działa. Czy to dobra praktyka? – Lynchy

4

MongoDB tak naprawdę nie obsługuje projekcji w taki sam sposób jak baz danych SQL; możesz poprosić o częściowy dokument, ale nadal będziesz otrzymywać coś, co pasuje do schematu dokumentu, którego dotyczyło zapytanie. W twoim przypadku otrzymujesz z powrotem tylko pole tasks, a dla każdego zadania tylko pole name.

można łatwo przekształcić to w listę ciągów przy użyciu zwykłego LINQ:

var categoryTasks = Categories.Find<Category>(x => x.CategoryName == catName) 
        .Project(Builders<Category>.Projection 
               .Include("tasks.name") 
               .Exclude("_id")) 
        .ToListAsync() 
        .Result; 

var taskNames = categoryTasks.Tasks.Select(task => task.Name).ToList(); 

Alternatywnie, można zrobić kilka wymyślnych rzeczy z agregacji API (która nie wspiera własne projekcje, trochę), ale że prawdopodobnie będzie to przesada dla ciebie.

Powiązane problemy