Cosmos SQL DAO (Data Access Object)
up vote
0
down vote
favorite
In my IoT project, I have cosmos DB to store telemetric and other business data.
I'm implementing DAO pattern first time, looking for better and reusable code suggestion.
DAO & Repository pattern solve same problem, I don't have any Entity (which directly map with cosmos DB collection), Single Cosmos DB collection storing multiple type of data that is why I implemented DAO pattern.
BaseDAO
public abstract class BaseDAO : IBaseDAO
{
public readonly DocumentClient client;
protected BaseDAO(IAppConfiguration appConfiguration)
{
this.client = new DocumentClient(appConfiguration.DatabaseEndPoint, appConfiguration.DatabaseKey,
new ConnectionPolicy
{
//ConnectionMode.Direct is fastest, but not recommended in consumption plan
ConnectionMode = ConnectionMode.Direct,
ConnectionProtocol = Protocol.Tcp,
// Customize retry options for Throttled requests
RetryOptions = new RetryOptions()
{
MaxRetryAttemptsOnThrottledRequests = 10,
MaxRetryWaitTimeInSeconds = 30
}
});
}
/// <summary>
/// Create Document in Database
/// </summary>
/// <param name="databaseId">database name</param>
/// <param name="collectionId">collection name</param>
/// <param name="document">document object</param>
/// <returns></returns>
public virtual async Task<string> CreateAsync(string databaseId, string collectionId, JObject document)
{
Document response = await this.client.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(databaseId, collectionId), document);
return response.Id;
}
/// <summary>
/// Delete document from database
/// </summary>
/// <param name="databaseId">database name</param>
/// <param name="collectionId">collection name</param>
/// <param name="id">document unique id</param>
/// <returns></returns>
public virtual async Task<bool> DeleteAsync(string databaseId, string collectionId, string id)
{
await this.client.DeleteDocumentAsync(UriFactory.CreateDocumentUri(databaseId, collectionId, id));
return true;
}
/// <summary>
/// Delete document from database
/// </summary>
/// <param name="databaseId">database name</param>
/// <param name="collectionId">collection name</param>
/// <param name="id">document unique id</param>
/// /// <param name="partitionKey"> document Partition key</param>
/// <returns></returns>
public virtual async Task<bool> DeleteWithPartitionKeyAsync(string databaseId, string collectionId, string id, string partitionKey)
{
await this.client.DeleteDocumentAsync(UriFactory.CreateDocumentUri(databaseId, collectionId, id), new RequestOptions { PartitionKey = new PartitionKey(partitionKey) });
return true;
}
/// <summary>
/// Get document by id
/// </summary>
/// <param name="databaseId">database name</param>
/// <param name="collectionId">collection name</param>
/// <param name="id">document unique id</param>
/// <returns></returns>
public virtual string GetDocumentById(string databaseId, string collectionId, string id)
{
var query = new SqlQuerySpec(
"SELECT * FROM c where c.id = @id",
new SqlParameterCollection(new SqlParameter { new SqlParameter { Name = "@id", Value = id }
}));
Document document = this.client.CreateDocumentQuery<dynamic>(UriFactory.CreateDocumentCollectionUri(databaseId, collectionId), query)
.AsEnumerable().FirstOrDefault();
return Serialize(document);
}
/// <summary>
/// Get list of document with filter criteria
/// </summary>
/// <param name="databaseId">database name</param>
/// <param name="collectionId">collection name</param>
/// <param name="conditions">filter condition</param>
/// <returns></returns>
public virtual JArray GetDocuments(string databaseId, string collectionId, Dictionary<string, string> conditions)
{
if (conditions.Count == 0)
throw new ArgumentException("Condition can't be blank");
SqlParameterCollection parameters = new SqlParameterCollection();
StringBuilder whereCondition = new StringBuilder();
foreach (var condition in conditions)
{
parameters.Add(new SqlParameter { Name = $"@{condition.Key}", Value = condition.Value });
whereCondition.Append($"c.{condition.Key} = @{condition.Key} and ");
}
string where = whereCondition.ToString().Remove(whereCondition.ToString().LastIndexOf(" and "));
var query = new SqlQuerySpec(
$"SELECT * FROM c where {where}", parameters);
List<Document> documents = this.client.CreateDocumentQuery<Document>(UriFactory.CreateDocumentCollectionUri(databaseId, collectionId), query)
.AsEnumerable().ToList();
return JArray.Parse(Serialize(documents));
}
public virtual T GetDocument<T>(string databaseId, string collectionId, Dictionary<string, string> conditions)
{
JArray documents = GetDocuments(databaseId, collectionId, conditions);
if (documents.Count > 0)
{
return JsonConvert.DeserializeObject<T>(documents.First().ToString());
}
else
{
return default(T);
}
}
/// <summary>
/// Update document in collection by id
/// </summary>
/// <param name="databaseId">database name</param>
/// <param name="collectionId">collection name</param>
/// <param name="id">document unique id</param>
/// <param name="newDocument">New document object</param>
/// <returns></returns>
public virtual async Task<bool> UpdateAsync(string databaseId, string collectionId, string id, JObject newDocument)
{
await this.client.ReplaceDocumentAsync(UriFactory.CreateDocumentUri(databaseId, collectionId, id), newDocument);
return true;
}
public virtual string Serialize(object obj)
{
return JsonConvert.SerializeObject(obj);
}
public virtual T Deserialize<T>(string serialized)
{
return JsonConvert.DeserializeObject<T>(serialized);
}
}
MasterData Collection DAO
public class MasterDAO : BaseDAO, IMasterDAO
{
private readonly IAppConfiguration appConfiguration;
public MasterDAO(IAppConfiguration appConfiguration)
: base(appConfiguration)
{
this.appConfiguration = appConfiguration;
}
public Task<string> CreateAsync(JObject document)
{
return base.CreateAsync(appConfiguration.DatabaseId, AMSConstraints.MasterData, document);
}
public async Task<bool> DeleteAsset(string assetId, string assetType)
{
var parameters = new Dictionary<string, string>();
parameters.Add("assetid", assetId);
parameters.Add("assetType", assetType);
JArray documents = base.GetDocuments(appConfiguration.DatabaseId, AMSConstraints.MasterData, parameters);
if (documents.Count > 0)
{
string id = documents.First()["id"].ToString();
return await base.DeleteAsync(appConfiguration.DatabaseId, AMSConstraints.MasterData, id);
}
else
{
return false;
}
}
public JArray GetAssetBySerialNumber(IEnumerable<string> serialNumber)
{
//TODO: need to use parameter query (above parametrize query not working)
dynamic result = client.CreateDocumentQuery<dynamic>(
UriFactory.CreateDocumentCollectionUri(appConfiguration.DatabaseId, AMSConstraints.MasterData),
"select * FROM c where c.ApplicationName = 'Eroutes' and c.Device[0].SerialNumber IN (" + serialNumber.ListToString() + ")")
.AsEnumerable().ToList();
if (result != null && result.Count > 0)
return JArray.Parse(Serialize(result));
else
return JArray.Parse("");
}
public string GetAssetType(string make, string serialNumber)
{
var query = new SqlQuerySpec("select c.AssetType FROM c where c.ApplicationName = 'Eroutes' and c.Device[0].SerialNumber=@SerialNumber and c.Device[0].Make=@Make",
new SqlParameterCollection(new SqlParameter {
new SqlParameter { Name = "@SerialNumber", Value = serialNumber },
new SqlParameter { Name = "@Make", Value = make }
}));
dynamic result = client.CreateDocumentQuery<dynamic>(
UriFactory.CreateDocumentCollectionUri(appConfiguration.DatabaseId, AMSConstraints.MasterData), query)
.AsEnumerable().FirstOrDefault();
if (result != null)
{
var json = JObject.Parse(Serialize(result));
return json["AssetType"].ToString();
}
else
{
return string.Empty;
}
}
public async Task<bool> UpdateDocumentByAsset(string assetId, string assetType, JObject newDocument)
{
var parameters = new Dictionary<string, string>();
parameters.Add("assetid", assetId);
parameters.Add("assetType", assetType);
JArray document = base.GetDocuments(appConfiguration.DatabaseId, AMSConstraints.MasterData, parameters);
string id = document[0]["id"].ToString();
return await base.UpdateAsync(appConfiguration.DatabaseId, AMSConstraints.MasterData, id, newDocument);
}
}
c# azure-cosmosdb
add a comment |
up vote
0
down vote
favorite
In my IoT project, I have cosmos DB to store telemetric and other business data.
I'm implementing DAO pattern first time, looking for better and reusable code suggestion.
DAO & Repository pattern solve same problem, I don't have any Entity (which directly map with cosmos DB collection), Single Cosmos DB collection storing multiple type of data that is why I implemented DAO pattern.
BaseDAO
public abstract class BaseDAO : IBaseDAO
{
public readonly DocumentClient client;
protected BaseDAO(IAppConfiguration appConfiguration)
{
this.client = new DocumentClient(appConfiguration.DatabaseEndPoint, appConfiguration.DatabaseKey,
new ConnectionPolicy
{
//ConnectionMode.Direct is fastest, but not recommended in consumption plan
ConnectionMode = ConnectionMode.Direct,
ConnectionProtocol = Protocol.Tcp,
// Customize retry options for Throttled requests
RetryOptions = new RetryOptions()
{
MaxRetryAttemptsOnThrottledRequests = 10,
MaxRetryWaitTimeInSeconds = 30
}
});
}
/// <summary>
/// Create Document in Database
/// </summary>
/// <param name="databaseId">database name</param>
/// <param name="collectionId">collection name</param>
/// <param name="document">document object</param>
/// <returns></returns>
public virtual async Task<string> CreateAsync(string databaseId, string collectionId, JObject document)
{
Document response = await this.client.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(databaseId, collectionId), document);
return response.Id;
}
/// <summary>
/// Delete document from database
/// </summary>
/// <param name="databaseId">database name</param>
/// <param name="collectionId">collection name</param>
/// <param name="id">document unique id</param>
/// <returns></returns>
public virtual async Task<bool> DeleteAsync(string databaseId, string collectionId, string id)
{
await this.client.DeleteDocumentAsync(UriFactory.CreateDocumentUri(databaseId, collectionId, id));
return true;
}
/// <summary>
/// Delete document from database
/// </summary>
/// <param name="databaseId">database name</param>
/// <param name="collectionId">collection name</param>
/// <param name="id">document unique id</param>
/// /// <param name="partitionKey"> document Partition key</param>
/// <returns></returns>
public virtual async Task<bool> DeleteWithPartitionKeyAsync(string databaseId, string collectionId, string id, string partitionKey)
{
await this.client.DeleteDocumentAsync(UriFactory.CreateDocumentUri(databaseId, collectionId, id), new RequestOptions { PartitionKey = new PartitionKey(partitionKey) });
return true;
}
/// <summary>
/// Get document by id
/// </summary>
/// <param name="databaseId">database name</param>
/// <param name="collectionId">collection name</param>
/// <param name="id">document unique id</param>
/// <returns></returns>
public virtual string GetDocumentById(string databaseId, string collectionId, string id)
{
var query = new SqlQuerySpec(
"SELECT * FROM c where c.id = @id",
new SqlParameterCollection(new SqlParameter { new SqlParameter { Name = "@id", Value = id }
}));
Document document = this.client.CreateDocumentQuery<dynamic>(UriFactory.CreateDocumentCollectionUri(databaseId, collectionId), query)
.AsEnumerable().FirstOrDefault();
return Serialize(document);
}
/// <summary>
/// Get list of document with filter criteria
/// </summary>
/// <param name="databaseId">database name</param>
/// <param name="collectionId">collection name</param>
/// <param name="conditions">filter condition</param>
/// <returns></returns>
public virtual JArray GetDocuments(string databaseId, string collectionId, Dictionary<string, string> conditions)
{
if (conditions.Count == 0)
throw new ArgumentException("Condition can't be blank");
SqlParameterCollection parameters = new SqlParameterCollection();
StringBuilder whereCondition = new StringBuilder();
foreach (var condition in conditions)
{
parameters.Add(new SqlParameter { Name = $"@{condition.Key}", Value = condition.Value });
whereCondition.Append($"c.{condition.Key} = @{condition.Key} and ");
}
string where = whereCondition.ToString().Remove(whereCondition.ToString().LastIndexOf(" and "));
var query = new SqlQuerySpec(
$"SELECT * FROM c where {where}", parameters);
List<Document> documents = this.client.CreateDocumentQuery<Document>(UriFactory.CreateDocumentCollectionUri(databaseId, collectionId), query)
.AsEnumerable().ToList();
return JArray.Parse(Serialize(documents));
}
public virtual T GetDocument<T>(string databaseId, string collectionId, Dictionary<string, string> conditions)
{
JArray documents = GetDocuments(databaseId, collectionId, conditions);
if (documents.Count > 0)
{
return JsonConvert.DeserializeObject<T>(documents.First().ToString());
}
else
{
return default(T);
}
}
/// <summary>
/// Update document in collection by id
/// </summary>
/// <param name="databaseId">database name</param>
/// <param name="collectionId">collection name</param>
/// <param name="id">document unique id</param>
/// <param name="newDocument">New document object</param>
/// <returns></returns>
public virtual async Task<bool> UpdateAsync(string databaseId, string collectionId, string id, JObject newDocument)
{
await this.client.ReplaceDocumentAsync(UriFactory.CreateDocumentUri(databaseId, collectionId, id), newDocument);
return true;
}
public virtual string Serialize(object obj)
{
return JsonConvert.SerializeObject(obj);
}
public virtual T Deserialize<T>(string serialized)
{
return JsonConvert.DeserializeObject<T>(serialized);
}
}
MasterData Collection DAO
public class MasterDAO : BaseDAO, IMasterDAO
{
private readonly IAppConfiguration appConfiguration;
public MasterDAO(IAppConfiguration appConfiguration)
: base(appConfiguration)
{
this.appConfiguration = appConfiguration;
}
public Task<string> CreateAsync(JObject document)
{
return base.CreateAsync(appConfiguration.DatabaseId, AMSConstraints.MasterData, document);
}
public async Task<bool> DeleteAsset(string assetId, string assetType)
{
var parameters = new Dictionary<string, string>();
parameters.Add("assetid", assetId);
parameters.Add("assetType", assetType);
JArray documents = base.GetDocuments(appConfiguration.DatabaseId, AMSConstraints.MasterData, parameters);
if (documents.Count > 0)
{
string id = documents.First()["id"].ToString();
return await base.DeleteAsync(appConfiguration.DatabaseId, AMSConstraints.MasterData, id);
}
else
{
return false;
}
}
public JArray GetAssetBySerialNumber(IEnumerable<string> serialNumber)
{
//TODO: need to use parameter query (above parametrize query not working)
dynamic result = client.CreateDocumentQuery<dynamic>(
UriFactory.CreateDocumentCollectionUri(appConfiguration.DatabaseId, AMSConstraints.MasterData),
"select * FROM c where c.ApplicationName = 'Eroutes' and c.Device[0].SerialNumber IN (" + serialNumber.ListToString() + ")")
.AsEnumerable().ToList();
if (result != null && result.Count > 0)
return JArray.Parse(Serialize(result));
else
return JArray.Parse("");
}
public string GetAssetType(string make, string serialNumber)
{
var query = new SqlQuerySpec("select c.AssetType FROM c where c.ApplicationName = 'Eroutes' and c.Device[0].SerialNumber=@SerialNumber and c.Device[0].Make=@Make",
new SqlParameterCollection(new SqlParameter {
new SqlParameter { Name = "@SerialNumber", Value = serialNumber },
new SqlParameter { Name = "@Make", Value = make }
}));
dynamic result = client.CreateDocumentQuery<dynamic>(
UriFactory.CreateDocumentCollectionUri(appConfiguration.DatabaseId, AMSConstraints.MasterData), query)
.AsEnumerable().FirstOrDefault();
if (result != null)
{
var json = JObject.Parse(Serialize(result));
return json["AssetType"].ToString();
}
else
{
return string.Empty;
}
}
public async Task<bool> UpdateDocumentByAsset(string assetId, string assetType, JObject newDocument)
{
var parameters = new Dictionary<string, string>();
parameters.Add("assetid", assetId);
parameters.Add("assetType", assetType);
JArray document = base.GetDocuments(appConfiguration.DatabaseId, AMSConstraints.MasterData, parameters);
string id = document[0]["id"].ToString();
return await base.UpdateAsync(appConfiguration.DatabaseId, AMSConstraints.MasterData, id, newDocument);
}
}
c# azure-cosmosdb
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
In my IoT project, I have cosmos DB to store telemetric and other business data.
I'm implementing DAO pattern first time, looking for better and reusable code suggestion.
DAO & Repository pattern solve same problem, I don't have any Entity (which directly map with cosmos DB collection), Single Cosmos DB collection storing multiple type of data that is why I implemented DAO pattern.
BaseDAO
public abstract class BaseDAO : IBaseDAO
{
public readonly DocumentClient client;
protected BaseDAO(IAppConfiguration appConfiguration)
{
this.client = new DocumentClient(appConfiguration.DatabaseEndPoint, appConfiguration.DatabaseKey,
new ConnectionPolicy
{
//ConnectionMode.Direct is fastest, but not recommended in consumption plan
ConnectionMode = ConnectionMode.Direct,
ConnectionProtocol = Protocol.Tcp,
// Customize retry options for Throttled requests
RetryOptions = new RetryOptions()
{
MaxRetryAttemptsOnThrottledRequests = 10,
MaxRetryWaitTimeInSeconds = 30
}
});
}
/// <summary>
/// Create Document in Database
/// </summary>
/// <param name="databaseId">database name</param>
/// <param name="collectionId">collection name</param>
/// <param name="document">document object</param>
/// <returns></returns>
public virtual async Task<string> CreateAsync(string databaseId, string collectionId, JObject document)
{
Document response = await this.client.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(databaseId, collectionId), document);
return response.Id;
}
/// <summary>
/// Delete document from database
/// </summary>
/// <param name="databaseId">database name</param>
/// <param name="collectionId">collection name</param>
/// <param name="id">document unique id</param>
/// <returns></returns>
public virtual async Task<bool> DeleteAsync(string databaseId, string collectionId, string id)
{
await this.client.DeleteDocumentAsync(UriFactory.CreateDocumentUri(databaseId, collectionId, id));
return true;
}
/// <summary>
/// Delete document from database
/// </summary>
/// <param name="databaseId">database name</param>
/// <param name="collectionId">collection name</param>
/// <param name="id">document unique id</param>
/// /// <param name="partitionKey"> document Partition key</param>
/// <returns></returns>
public virtual async Task<bool> DeleteWithPartitionKeyAsync(string databaseId, string collectionId, string id, string partitionKey)
{
await this.client.DeleteDocumentAsync(UriFactory.CreateDocumentUri(databaseId, collectionId, id), new RequestOptions { PartitionKey = new PartitionKey(partitionKey) });
return true;
}
/// <summary>
/// Get document by id
/// </summary>
/// <param name="databaseId">database name</param>
/// <param name="collectionId">collection name</param>
/// <param name="id">document unique id</param>
/// <returns></returns>
public virtual string GetDocumentById(string databaseId, string collectionId, string id)
{
var query = new SqlQuerySpec(
"SELECT * FROM c where c.id = @id",
new SqlParameterCollection(new SqlParameter { new SqlParameter { Name = "@id", Value = id }
}));
Document document = this.client.CreateDocumentQuery<dynamic>(UriFactory.CreateDocumentCollectionUri(databaseId, collectionId), query)
.AsEnumerable().FirstOrDefault();
return Serialize(document);
}
/// <summary>
/// Get list of document with filter criteria
/// </summary>
/// <param name="databaseId">database name</param>
/// <param name="collectionId">collection name</param>
/// <param name="conditions">filter condition</param>
/// <returns></returns>
public virtual JArray GetDocuments(string databaseId, string collectionId, Dictionary<string, string> conditions)
{
if (conditions.Count == 0)
throw new ArgumentException("Condition can't be blank");
SqlParameterCollection parameters = new SqlParameterCollection();
StringBuilder whereCondition = new StringBuilder();
foreach (var condition in conditions)
{
parameters.Add(new SqlParameter { Name = $"@{condition.Key}", Value = condition.Value });
whereCondition.Append($"c.{condition.Key} = @{condition.Key} and ");
}
string where = whereCondition.ToString().Remove(whereCondition.ToString().LastIndexOf(" and "));
var query = new SqlQuerySpec(
$"SELECT * FROM c where {where}", parameters);
List<Document> documents = this.client.CreateDocumentQuery<Document>(UriFactory.CreateDocumentCollectionUri(databaseId, collectionId), query)
.AsEnumerable().ToList();
return JArray.Parse(Serialize(documents));
}
public virtual T GetDocument<T>(string databaseId, string collectionId, Dictionary<string, string> conditions)
{
JArray documents = GetDocuments(databaseId, collectionId, conditions);
if (documents.Count > 0)
{
return JsonConvert.DeserializeObject<T>(documents.First().ToString());
}
else
{
return default(T);
}
}
/// <summary>
/// Update document in collection by id
/// </summary>
/// <param name="databaseId">database name</param>
/// <param name="collectionId">collection name</param>
/// <param name="id">document unique id</param>
/// <param name="newDocument">New document object</param>
/// <returns></returns>
public virtual async Task<bool> UpdateAsync(string databaseId, string collectionId, string id, JObject newDocument)
{
await this.client.ReplaceDocumentAsync(UriFactory.CreateDocumentUri(databaseId, collectionId, id), newDocument);
return true;
}
public virtual string Serialize(object obj)
{
return JsonConvert.SerializeObject(obj);
}
public virtual T Deserialize<T>(string serialized)
{
return JsonConvert.DeserializeObject<T>(serialized);
}
}
MasterData Collection DAO
public class MasterDAO : BaseDAO, IMasterDAO
{
private readonly IAppConfiguration appConfiguration;
public MasterDAO(IAppConfiguration appConfiguration)
: base(appConfiguration)
{
this.appConfiguration = appConfiguration;
}
public Task<string> CreateAsync(JObject document)
{
return base.CreateAsync(appConfiguration.DatabaseId, AMSConstraints.MasterData, document);
}
public async Task<bool> DeleteAsset(string assetId, string assetType)
{
var parameters = new Dictionary<string, string>();
parameters.Add("assetid", assetId);
parameters.Add("assetType", assetType);
JArray documents = base.GetDocuments(appConfiguration.DatabaseId, AMSConstraints.MasterData, parameters);
if (documents.Count > 0)
{
string id = documents.First()["id"].ToString();
return await base.DeleteAsync(appConfiguration.DatabaseId, AMSConstraints.MasterData, id);
}
else
{
return false;
}
}
public JArray GetAssetBySerialNumber(IEnumerable<string> serialNumber)
{
//TODO: need to use parameter query (above parametrize query not working)
dynamic result = client.CreateDocumentQuery<dynamic>(
UriFactory.CreateDocumentCollectionUri(appConfiguration.DatabaseId, AMSConstraints.MasterData),
"select * FROM c where c.ApplicationName = 'Eroutes' and c.Device[0].SerialNumber IN (" + serialNumber.ListToString() + ")")
.AsEnumerable().ToList();
if (result != null && result.Count > 0)
return JArray.Parse(Serialize(result));
else
return JArray.Parse("");
}
public string GetAssetType(string make, string serialNumber)
{
var query = new SqlQuerySpec("select c.AssetType FROM c where c.ApplicationName = 'Eroutes' and c.Device[0].SerialNumber=@SerialNumber and c.Device[0].Make=@Make",
new SqlParameterCollection(new SqlParameter {
new SqlParameter { Name = "@SerialNumber", Value = serialNumber },
new SqlParameter { Name = "@Make", Value = make }
}));
dynamic result = client.CreateDocumentQuery<dynamic>(
UriFactory.CreateDocumentCollectionUri(appConfiguration.DatabaseId, AMSConstraints.MasterData), query)
.AsEnumerable().FirstOrDefault();
if (result != null)
{
var json = JObject.Parse(Serialize(result));
return json["AssetType"].ToString();
}
else
{
return string.Empty;
}
}
public async Task<bool> UpdateDocumentByAsset(string assetId, string assetType, JObject newDocument)
{
var parameters = new Dictionary<string, string>();
parameters.Add("assetid", assetId);
parameters.Add("assetType", assetType);
JArray document = base.GetDocuments(appConfiguration.DatabaseId, AMSConstraints.MasterData, parameters);
string id = document[0]["id"].ToString();
return await base.UpdateAsync(appConfiguration.DatabaseId, AMSConstraints.MasterData, id, newDocument);
}
}
c# azure-cosmosdb
In my IoT project, I have cosmos DB to store telemetric and other business data.
I'm implementing DAO pattern first time, looking for better and reusable code suggestion.
DAO & Repository pattern solve same problem, I don't have any Entity (which directly map with cosmos DB collection), Single Cosmos DB collection storing multiple type of data that is why I implemented DAO pattern.
BaseDAO
public abstract class BaseDAO : IBaseDAO
{
public readonly DocumentClient client;
protected BaseDAO(IAppConfiguration appConfiguration)
{
this.client = new DocumentClient(appConfiguration.DatabaseEndPoint, appConfiguration.DatabaseKey,
new ConnectionPolicy
{
//ConnectionMode.Direct is fastest, but not recommended in consumption plan
ConnectionMode = ConnectionMode.Direct,
ConnectionProtocol = Protocol.Tcp,
// Customize retry options for Throttled requests
RetryOptions = new RetryOptions()
{
MaxRetryAttemptsOnThrottledRequests = 10,
MaxRetryWaitTimeInSeconds = 30
}
});
}
/// <summary>
/// Create Document in Database
/// </summary>
/// <param name="databaseId">database name</param>
/// <param name="collectionId">collection name</param>
/// <param name="document">document object</param>
/// <returns></returns>
public virtual async Task<string> CreateAsync(string databaseId, string collectionId, JObject document)
{
Document response = await this.client.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(databaseId, collectionId), document);
return response.Id;
}
/// <summary>
/// Delete document from database
/// </summary>
/// <param name="databaseId">database name</param>
/// <param name="collectionId">collection name</param>
/// <param name="id">document unique id</param>
/// <returns></returns>
public virtual async Task<bool> DeleteAsync(string databaseId, string collectionId, string id)
{
await this.client.DeleteDocumentAsync(UriFactory.CreateDocumentUri(databaseId, collectionId, id));
return true;
}
/// <summary>
/// Delete document from database
/// </summary>
/// <param name="databaseId">database name</param>
/// <param name="collectionId">collection name</param>
/// <param name="id">document unique id</param>
/// /// <param name="partitionKey"> document Partition key</param>
/// <returns></returns>
public virtual async Task<bool> DeleteWithPartitionKeyAsync(string databaseId, string collectionId, string id, string partitionKey)
{
await this.client.DeleteDocumentAsync(UriFactory.CreateDocumentUri(databaseId, collectionId, id), new RequestOptions { PartitionKey = new PartitionKey(partitionKey) });
return true;
}
/// <summary>
/// Get document by id
/// </summary>
/// <param name="databaseId">database name</param>
/// <param name="collectionId">collection name</param>
/// <param name="id">document unique id</param>
/// <returns></returns>
public virtual string GetDocumentById(string databaseId, string collectionId, string id)
{
var query = new SqlQuerySpec(
"SELECT * FROM c where c.id = @id",
new SqlParameterCollection(new SqlParameter { new SqlParameter { Name = "@id", Value = id }
}));
Document document = this.client.CreateDocumentQuery<dynamic>(UriFactory.CreateDocumentCollectionUri(databaseId, collectionId), query)
.AsEnumerable().FirstOrDefault();
return Serialize(document);
}
/// <summary>
/// Get list of document with filter criteria
/// </summary>
/// <param name="databaseId">database name</param>
/// <param name="collectionId">collection name</param>
/// <param name="conditions">filter condition</param>
/// <returns></returns>
public virtual JArray GetDocuments(string databaseId, string collectionId, Dictionary<string, string> conditions)
{
if (conditions.Count == 0)
throw new ArgumentException("Condition can't be blank");
SqlParameterCollection parameters = new SqlParameterCollection();
StringBuilder whereCondition = new StringBuilder();
foreach (var condition in conditions)
{
parameters.Add(new SqlParameter { Name = $"@{condition.Key}", Value = condition.Value });
whereCondition.Append($"c.{condition.Key} = @{condition.Key} and ");
}
string where = whereCondition.ToString().Remove(whereCondition.ToString().LastIndexOf(" and "));
var query = new SqlQuerySpec(
$"SELECT * FROM c where {where}", parameters);
List<Document> documents = this.client.CreateDocumentQuery<Document>(UriFactory.CreateDocumentCollectionUri(databaseId, collectionId), query)
.AsEnumerable().ToList();
return JArray.Parse(Serialize(documents));
}
public virtual T GetDocument<T>(string databaseId, string collectionId, Dictionary<string, string> conditions)
{
JArray documents = GetDocuments(databaseId, collectionId, conditions);
if (documents.Count > 0)
{
return JsonConvert.DeserializeObject<T>(documents.First().ToString());
}
else
{
return default(T);
}
}
/// <summary>
/// Update document in collection by id
/// </summary>
/// <param name="databaseId">database name</param>
/// <param name="collectionId">collection name</param>
/// <param name="id">document unique id</param>
/// <param name="newDocument">New document object</param>
/// <returns></returns>
public virtual async Task<bool> UpdateAsync(string databaseId, string collectionId, string id, JObject newDocument)
{
await this.client.ReplaceDocumentAsync(UriFactory.CreateDocumentUri(databaseId, collectionId, id), newDocument);
return true;
}
public virtual string Serialize(object obj)
{
return JsonConvert.SerializeObject(obj);
}
public virtual T Deserialize<T>(string serialized)
{
return JsonConvert.DeserializeObject<T>(serialized);
}
}
MasterData Collection DAO
public class MasterDAO : BaseDAO, IMasterDAO
{
private readonly IAppConfiguration appConfiguration;
public MasterDAO(IAppConfiguration appConfiguration)
: base(appConfiguration)
{
this.appConfiguration = appConfiguration;
}
public Task<string> CreateAsync(JObject document)
{
return base.CreateAsync(appConfiguration.DatabaseId, AMSConstraints.MasterData, document);
}
public async Task<bool> DeleteAsset(string assetId, string assetType)
{
var parameters = new Dictionary<string, string>();
parameters.Add("assetid", assetId);
parameters.Add("assetType", assetType);
JArray documents = base.GetDocuments(appConfiguration.DatabaseId, AMSConstraints.MasterData, parameters);
if (documents.Count > 0)
{
string id = documents.First()["id"].ToString();
return await base.DeleteAsync(appConfiguration.DatabaseId, AMSConstraints.MasterData, id);
}
else
{
return false;
}
}
public JArray GetAssetBySerialNumber(IEnumerable<string> serialNumber)
{
//TODO: need to use parameter query (above parametrize query not working)
dynamic result = client.CreateDocumentQuery<dynamic>(
UriFactory.CreateDocumentCollectionUri(appConfiguration.DatabaseId, AMSConstraints.MasterData),
"select * FROM c where c.ApplicationName = 'Eroutes' and c.Device[0].SerialNumber IN (" + serialNumber.ListToString() + ")")
.AsEnumerable().ToList();
if (result != null && result.Count > 0)
return JArray.Parse(Serialize(result));
else
return JArray.Parse("");
}
public string GetAssetType(string make, string serialNumber)
{
var query = new SqlQuerySpec("select c.AssetType FROM c where c.ApplicationName = 'Eroutes' and c.Device[0].SerialNumber=@SerialNumber and c.Device[0].Make=@Make",
new SqlParameterCollection(new SqlParameter {
new SqlParameter { Name = "@SerialNumber", Value = serialNumber },
new SqlParameter { Name = "@Make", Value = make }
}));
dynamic result = client.CreateDocumentQuery<dynamic>(
UriFactory.CreateDocumentCollectionUri(appConfiguration.DatabaseId, AMSConstraints.MasterData), query)
.AsEnumerable().FirstOrDefault();
if (result != null)
{
var json = JObject.Parse(Serialize(result));
return json["AssetType"].ToString();
}
else
{
return string.Empty;
}
}
public async Task<bool> UpdateDocumentByAsset(string assetId, string assetType, JObject newDocument)
{
var parameters = new Dictionary<string, string>();
parameters.Add("assetid", assetId);
parameters.Add("assetType", assetType);
JArray document = base.GetDocuments(appConfiguration.DatabaseId, AMSConstraints.MasterData, parameters);
string id = document[0]["id"].ToString();
return await base.UpdateAsync(appConfiguration.DatabaseId, AMSConstraints.MasterData, id, newDocument);
}
}
c# azure-cosmosdb
c# azure-cosmosdb
edited 1 min ago
t3chb0t
33.6k744108
33.6k744108
asked 41 mins ago
Pankaj Rawat
1146
1146
add a comment |
add a comment |
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f208211%2fcosmos-sql-dao-data-access-object%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown