Как правильно получить все элементы из DocumentDB через webapi - PullRequest
0 голосов
/ 06 июля 2018

У меня есть следующий вспомогательный класс репозитория DocumentDB

using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Documents.Linq;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using System.Web;

namespace TenantManagementWebApi.DataAccess
{
    public static class DocumentDBRepository<T> where T : class
    {
        private static readonly string DatabaseId = ConfigurationManager.AppSettings["database"];
        private static readonly string CollectionId = ConfigurationManager.AppSettings["collection"];
        private static DocumentClient client;

        public static async Task<T> GetItemAsync(string id)
        {
            try
            {
                Document document = await client.ReadDocumentAsync(UriFactory.CreateDocumentUri(DatabaseId, CollectionId, id));
                return (T)(dynamic)document;
            }
            catch (DocumentClientException e)
            {
                if (e.StatusCode == System.Net.HttpStatusCode.NotFound)
                {
                    return null;
                }
                else
                {
                    throw;
                }
            }
        }

        public static async Task<IEnumerable<T>> GetItemsAsync(Expression<Func<T, bool>> predicate)
        {
            IDocumentQuery<T> query = client.CreateDocumentQuery<T>(
                UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId),
                new FeedOptions { MaxItemCount = -1 })
                .Where(predicate)
                .AsDocumentQuery();

            List<T> results = new List<T>();
            while (query.HasMoreResults)
            {
                results.AddRange(await query.ExecuteNextAsync<T>());
            }

            return results;
        }

        public static async Task<Document> CreateItemAsync(T item)
        {
            return await client.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId), item);
        }

        public static async Task<Document> UpdateItemAsync(string id, T item)
        {
            return await client.ReplaceDocumentAsync(UriFactory.CreateDocumentUri(DatabaseId, CollectionId, id), item);
        }

        public static async Task DeleteItemAsync(string id)
        {
            await client.DeleteDocumentAsync(UriFactory.CreateDocumentUri(DatabaseId, CollectionId, id));
        }

        public static void Initialize()
        {
            client = new DocumentClient(new Uri(ConfigurationManager.AppSettings["endpoint"]), ConfigurationManager.AppSettings["authKey"]);
            CreateDatabaseIfNotExistsAsync().Wait();
            CreateCollectionIfNotExistsAsync().Wait();
        }

        private static async Task CreateDatabaseIfNotExistsAsync()
        {
            try
            {
                await client.ReadDatabaseAsync(UriFactory.CreateDatabaseUri(DatabaseId));
            }
            catch (DocumentClientException e)
            {
                if (e.StatusCode == System.Net.HttpStatusCode.NotFound)
                {
                    await client.CreateDatabaseAsync(new Database { Id = DatabaseId });
                }
                else
                {
                    throw;
                }
            }
        }

        private static async Task CreateCollectionIfNotExistsAsync()
        {
            try
            {
                await client.ReadDocumentCollectionAsync(UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId));
            }
            catch (DocumentClientException e)
            {
                if (e.StatusCode == System.Net.HttpStatusCode.NotFound)
                {
                    await client.CreateDocumentCollectionAsync(
                        UriFactory.CreateDatabaseUri(DatabaseId),
                        new DocumentCollection { Id = CollectionId },
                        new RequestOptions { OfferThroughput = 1000 });
                }
                else
                {
                    throw;
                }
            }
        }
    }
}

И мне нужно сделать контроллер webapi crud для одной сущности:

 public class Tenant
    {
        public string TenantId { get; set; }
        public string TenantUrl { get; set; }
        public string CertificatePath { get; set; }
        public string CertificatePassword { get; set; }

        public override string ToString()
        {
            return JsonConvert.SerializeObject(this);
        }
    }

Я не уверен, что положить в Предикат, чтобы получить все предметы, которые Арендатор.

 public async Task<List<Tenant>> GetTenants()
        {
            return await  DocumentDBRepository<List<Tenant>>.GetItemsAsync(d => d. != null);
        }

1 Ответ

0 голосов
/ 06 июля 2018

Вам нужно сделать свой общий T объект более конкретным. Ограничьте его классом, который реализует некоторый интерфейс, такой как ICosmosEntity, и добавьте свойство EntityType для этого интерфейса.

Затем заставьте свои DTO реализовывать этот интерфейс и установите EntityType на имя класса. Таким образом, вы можете создать динамический предикат, который получает nameof(T) и автоматически добавляет его в предложение Where вашего запроса LINQ.

Если вы просто хотите получить все элементы в коллекции, то в вашем коде предикат x => true сделает это, но не ограничит его в арендаторах, если в коллекции нет только объектов-арендаторов.

Также ReadDocumentAsync будет иметь смысл только в том случае, если в вашей коллекции нет ключа раздела (что на самом деле не рекомендуется)

Возможно, стоит взглянуть на Космонавт , поскольку он делает именно то, что вы хотите, и даже больше. Он поддерживает ту же логику совместного использования коллекций , которую вы пытаетесь кодировать.

Отказ от ответственности, я создатель Космонавта.

...