我正在使用cosmos DB,并且已经在以下通用存储库中创建了CRUD操作。
public class CosmosDBRepository : ICosmosDBRepository
{
private readonly DocumentClient _client;
private readonly string DatabaseId = "FleetHub";
public CosmosDBRepository()
{
var endpoint = CloudConfigurationManager.GetSetting("CosmoDbEndpoint");
var authkey = CloudConfigurationManager.GetSetting("CosmoDbAuthKey");
try
{
if (endpoint == null || authkey == null)
{
throw new ArgumentNullException("CosmoDbEndpoint or CosmoDbAuthKey could not be found in the config file, check your settings.");
}
if (_client == null)
{
_client = new DocumentClient(new Uri(endpoint), authkey, connectionPolicy: new ConnectionPolicy { EnableEndpointDiscovery = false });
}
CreateDatabaseIfNotExistsAsync().Wait();
CreateCollectionIfNotExistsAsync().Wait();
}
catch (Exception e)
{
throw new Exception($"Initialise failed CosmoDbEndpoint {endpoint} or CosmoDbAuthKey {authkey} could not be found in the config file, check your settings. {e.Message}");
}
}
/// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <param name="partitionkey"></param>
/// <returns></returns>
public async Task<T> GetItemAsync<T>(string id, string partitionkey) where T : class
{
try
{
string CollectionId = GetAttributeCosmoDbCollection<T>(typeof(T));
Document document = await _client.ReadDocumentAsync(UriFactory.CreateDocumentUri(DatabaseId, CollectionId, id), new RequestOptions { PartitionKey = new PartitionKey(partitionkey) });
return (T)(dynamic)document;
}
catch (DocumentClientException e)
{
if (e.StatusCode == System.Net.HttpStatusCode.NotFound)
{
return null;
}
else
{
throw;
}
}
}
/// <summary>
///
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public async Task<Document> CreateItemAsync<T>(T item) where T : class
{
string CollectionId = GetAttributeCosmoDbCollection<T>(typeof(T));
return await _client.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId), item);
}
public async Task<IEnumerable<T>> GetItemsAsync<T>(Expression<Func<T, bool>> predicate, Expression<Func<T, object>> orderByDesc, int takeCount = -1)
where T : class
{
string CollectionId = GetAttributeCosmoDbCollection<T>(typeof(T));
var criteria = _client.CreateDocumentQuery<T>(
UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId), new FeedOptions { EnableCrossPartitionQuery = true })
.Where(predicate)
.OrderByDescending(orderByDesc)
.AsDocumentQuery();
IDocumentQuery<T> query = criteria;
List<T> results = new List<T>();
while (query.HasMoreResults)
{
if (takeCount > -1 && results.Count >= takeCount)
{
break;
}
results.AddRange(await query.ExecuteNextAsync<T>());
}
return results;
}
/// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <param name="item"></param>
/// <returns></returns>
public async Task<Document> UpdateItemAsync<T>(string id, T item) where T : class
{
string CollectionId = GetAttributeCosmoDbCollection<T>(typeof(T));
return await _client.ReplaceDocumentAsync(UriFactory.CreateDocumentUri(DatabaseId, CollectionId, id), item);
}
#region private methods
private 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;
}
}
}
/// <summary>
///
/// </summary>
/// <param name="t"></param>
/// <returns></returns>
private string GetPartitionKeyAttributeCosmoDbCollection(Type t)
{
// Get instance of the attribute.
CosmoDBCollection attribute =
(CosmoDBCollection)Attribute.GetCustomAttribute(t, typeof(CosmoDBCollection));
if (attribute == null)
{
throw new Exception("The attribute CosmoDbCollection was not found.");
}
return attribute.PartitionKey;
}
private string GetAttributeCosmoDbCollection<T>(Type t) where T : class
{
// Get instance of the attribute.
CosmoDBCollection attribute =
(CosmoDBCollection)Attribute.GetCustomAttribute(t, typeof(CosmoDBCollection));
if (attribute == null)
{
throw new Exception("The attribute CosmoDbCollection was not found.");
}
return attribute.Name;
}
#endregion
}
这是CosmoDBCollection类:
public class CosmoDBCollection : Attribute
{
public string Name { get; set; }
public string PartitionKey { get; set; }
}
我在构造函数中调用CreateCollectionIfNotExistsAsync().Wait();
,此方法需要collectionId。如何将CollectionId传递给此方法?因为这是通用存储库。
我需要创建通用CreateCollectionIfNotExistsAsync()
方法吗?
答案 0 :(得分:0)
如果您的集合名称基于<T>
,为什么不简单将CosmosDBRepository<T>
作为实际类。这样,您还可以在构造函数上获取值。
理想情况下,它也将是readonly
私有属性,您只需(在构造函数上)计算一次,并在所有操作上重用,以避免以后支付构造它的成本(因为它不变)。