问题
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 Employee
in 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