DocumentDB show all documents of specific entity type

被刻印的时光 ゝ 提交于 2020-01-16 20:25:13

问题


I have a generic IDocumentDbRepository repository for providing basic CRUD operations with DocumentDB and specific repositories for additional operations with specific entities, which inherits or implements this interface and class.

    public interface IDocumentDbRepository<T> where T : class
{
    //IEnumerable<T> GetItems();
    Task<IEnumerable<T>> GetItemsAsync();
    Task<T> GetItemAsync(T id);
    Task<T> AddDocumentAsync(T item);
    Task<T> UpdateDocumentAsync(T id, T item);
    Task DeletedocumentAsync(T id);
}

public class DocumentDbRepository<T> : IDocumentDbRepository<T> where T : class
{
    private readonly string AuthKey;
    private readonly string EndpointUri;
    private readonly string DatabaseId;
    private readonly string CollectionId;
    private static DocumentClient client;


    public DocumentDbRepository(IOptions<DocumentDbSettings> DocumentDbConfig)
    {
        this.DatabaseId = DocumentDbConfig.Value.DatabaseName;
        this.CollectionId = DocumentDbConfig.Value.CollectionName;
        this.AuthKey = DocumentDbConfig.Value.AuthKey;
        this.EndpointUri = DocumentDbConfig.Value.EndpointUri;
        client = new DocumentClient(new Uri(EndpointUri), AuthKey);
    }

public async Task<IEnumerable<T>> GetItemsAsync()
{
     IDocumentQuery<T> query = client.CreateDocumentQuery<T>(
     UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId))
     .AsDocumentQuery();

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

   // public IEnumerable<T> GetItems()
   // {
   //     var results = client.CreateDocumentQuery<T>//(UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId)).ToList();
   //   return results;
   // }
//methods

In my specific Employee repository I aim to return only documents of type Employee

public interface IEmployeeRepository : IDocumentDbRepository<Employee>
{
    List<Employee> GetAllEmployees();
}

public class EmployeeRepository : DocumentDbRepository<Employee>, IEmployeeRepository
{
    public EmployeeRepository(IOptions<DocumentDbSettings> DocumentDbConfig) : base(DocumentDbConfig)
    {

    }

    public List<Employee> GetAllEmployees()
    {
        return GetItems().Where(x => x.GetType() == typeof(Employee)).ToList(); 
    }
}

I call GetAllEmployees method in my controller to only list Documents of Type Employeein my View, but it does not work and all documents with whatever entity type gets listed. What am I doing wrong ?

public IActionResult Index()
{
    return View(_employeeRepository.GetAllEmployees());
}

回答1:


Ok, several things.

First you should never call .ToList(); on CreateDocumentQuery like that. It will make multiple synchronous calls over the wire in order to return every single document in the database. This will cause insane RU/s and really bad performance.

Use AsDocumentQuery and call ExecuteNextAsync while query.HasMoreResults.

Second, by the time you call the ToList() method, everything is returned as an Employee because you queried for it that way. You basically said, "return me everything in this collection as an Employee and then from that return me the Employees". At this stage all of them are Employees.

What you really need is some sort of type property on your document which you can use to query for before you do the ToList call.

I would recommend you check how collection sharing works in Cosmonaut. Sounds exactly like something you need.

Here is how you can asynchronously call the ToList method without blocking the thread.

Disclaimer: I am the creator of Cosmonaut.



来源:https://stackoverflow.com/questions/51171569/documentdb-show-all-documents-of-specific-entity-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!