我有以下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);
}
答案 0 :(得分:1)
您需要使通用T
对象更加具体。将其限制为实现诸如ICosmosEntity
之类的接口的类,并在该接口上添加EntityType
属性。
然后使您的DTO实现该接口,并将EntityType
设置为类名。这样,您就可以创建一个动态谓词,该谓词获取nameof(T)
并自动将其添加到LINQ查询的Where
子句中。
如果您只想获取集合中的所有项目,那么在您的代码中,x => true
谓词可以做到这一点,但是除非集合中仅包含租户对象,否则它不会将它限制在租户中。
ReadDocumentAsync
仅在您的集合没有分区键时才值得这样做(不建议这样做)
也许值得一看Cosmonaut,因为它确实可以满足您的需求以及更多。它支持与您尝试编写的代码完全相同的collection sharing逻辑。
免责声明,我是宇航员的创造者。