Как использовать Linq Projection с IMongoQueryable <TEntity>в C # - PullRequest
1 голос
/ 14 октября 2019

Я использую C # 8, стандарт .net 2.0 с MongoDB.Driver v2.9.2. Я перевожу проект из RavenDB в MongoDB.

Мне нужно как-то использовать include с IMongoQueryable в моем методе GetAllAsync, но я запутался. Вот метод;

public async Task<ICollection<TEntity>> GetAllAsync<TOrderBy>(Expression<Func<TEntity, TOrderBy>> orderBy, 
                               bool isDescendingOrder = false, 
                               Expression<Func<TEntity, object>> projection = null,
                               CancellationToken cancellationToken = default)
        {
            IMongoQueryable<TEntity> mongoQueryable = Collection.AsQueryable();

            if (isDescendingOrder)
            {
                return await mongoQueryable.OrderByDescending(orderBy)
                                           .ToListAsync(cancellationToken: cancellationToken);
            }

            return await mongoQueryable.OrderBy(orderBy)
                                       .ToListAsync(cancellationToken: cancellationToken);
        }

То, что я пробовал до сих пор;Я могу построить тот же запрос с помощью метода «Find ()», но метод SortByDescending требует «Expression<Func<TEntity, object>> orderBy» - не может работать с Expression<Func<TEntity, TOrderBy>> orderBy, как блок верхнего кода, который я предоставил.

Builders<TEntity>.Sort.Ascending(orderBy).

Func<TEntity, TOrderBy> compile = orderBy.Compile();
Collection.Find(new BsonDocument()).Project(projection).SortByDescending(compile).ToListAsync();

И последнеевот что я решил в RavenDB:

public async Task<ICollection<TEntity>> GetAllAsync<TOrderBy>(Expression<Func<TEntity, TOrderBy>> orderBy, 
                                       bool isDescendingOrder = false, 
                                       Expression<Func<TEntity, object>> projection = null,
                                       CancellationToken cancellationToken = default)
        {
            ICollection<TEntity> entities;

            IRavenQueryable<TEntity> query = AsyncDocumentSession.Query<TEntity>();

            if (projection != null)
            {
                query = query.Include(projection);
            }

            if (isDescendingOrder)
            {
                entities = await query.OrderByDescending(orderBy)
                                      .ToListAsync(token: cancellationToken);
            }
            else
            {
                entities = await query.OrderBy(orderBy)
                                      .ToListAsync(token: cancellationToken);
            }

            return entities;
        }

1 Ответ

1 голос
/ 14 октября 2019

попробовать следующее:

        public static async Task<ICollection<TEntity>> GetAllAsync<TEntity, TOrderBy>
            (
            Expression<Func<TEntity, TOrderBy>> orderBy,
            bool isDescendingOrder = false,
            Expression<Func<TEntity, TEntity>> projection = null,
            CancellationToken cancellationToken = default
            )
        {
            var query = _collection.AsQueryable();

            var sortedQuery = isDescendingOrder ?
                                query.OrderByDescending(orderBy) :
                                query.OrderBy(orderBy);

            query = projection != null ?
                        sortedQuery.Select(projection) :
                        sortedQuery.Select(x=> x);

            return await query.ToListAsync(cancellationToken) as ICollection<TEntity>;
        }

тестовая программа:

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using MongoDB.Entities;
using MongoDB.Entities.Core;
using MongoDB.Driver.Linq;
using MongoDB.Driver;

namespace StackOverflow
{
    public class Person : Entity
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }

    public static class Program
    {
        public async static Task Main()
        {
            new DB("test");

            await (new Person { Name = "Person", Age = 22 }).SaveAsync();

            var result =
                await GetAllAsync<Person, object>(
                    p => p.Age,
                    true,
                    p => new Person { Name = p.Name, Age = p.Age });
        }

        public static async Task<ICollection<TEntity>> GetAllAsync<TEntity, TOrderBy>
            (
            Expression<Func<TEntity, TOrderBy>> orderBy,
            bool isDescendingOrder = false,
            Expression<Func<TEntity, TEntity>> projection = null,
            CancellationToken cancellationToken = default
            ) 
        {
            var query = DB.Queryable<TEntity>();

            var sortedQuery = isDescendingOrder ?
                                query.OrderByDescending(orderBy) :
                                query.OrderBy(orderBy);

            query = projection != null ?
                        sortedQuery.Select(projection) :
                        sortedQuery.Select(x=> x);

            return await query.ToListAsync(cancellationToken) as ICollection<TEntity>;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...