I am trying to execute n1ql like below
var query = $“UPDATE {BucketName} as d SET d.permissions = ARRAY_Append(d.permissions, {parameterList}) WHERE d.userId = $user”;
this query append parameters in a nested list.
query is tested inside management and it’s work. the problem is that data inserted but in Pascal Case format. other queries have not this issue. is it related to serializer?
I try to override serializer but it’s not working.
Can you provide the code where you’re building the query request? Especially the part where you build the parameterList parameter. That would be very helpful.
A couple of pointers that may also help:
- You’re building the query using a string format in C#. This should be done very carefully, as it can allow N1QL injection attacks (much like SQL injection attacks). Where possible, using named parameters is preferred.
- For a query like this, I would really recommend not using a query at all. This operation would be much faster as a sub-doc MutateIn operation. Something like this (from memory, syntax may not be quite right):
await collection.MutateInAsync($"user-{userId}", builder => {
builder.Append("permissions", valueToAppend);
});
thanks for reply. below is my code. PermissionCacheModel is a poco model in C#
public async Task<GenericResponseDto<bool>> AddPermissionsByUser(string userId, List<PermissionCacheModel> permissions)
{
try
{
var parameterList = "";
for (int i = 0; i < permissions.Count; i++)
{
parameterList += $"$param{i}";
if (i < permissions.Count - 1)
{
parameterList += ",";
}
}
var query = $"UPDATE {BucketName} as d SET d.permissions = ARRAY_Append(d.permissions, {parameterList}) WHERE d.userId = $user";
var cluster = await _cluster.GetClusterAsync();
var result = await cluster.QueryAsync<object>(query, opt =>
{
opt.Parameter("$user", userId);
for (int i = 0; i < permissions.Count; i++)
{
opt.Parameter($"$param{i}", permissions[i]);
}
});
return await GenericResponseGenerator<bool>.Ok(true);
}
catch (Exception e)
{
return await GenericResponseGenerator<bool>.Error(e.Message);
}
}
I’ve tested Sub-Document for my problem. It rocks! . Thanks for your suggestion. But another issue with builder.Append() is its append as a list (with brackets) not a separate object for each T[]
value.
@tester I believe you need to call .Append for each object in your array, rather than calling .Append once and passing it an array.
I found the issue. Append() takes the second parameter as an array. passing a list to it cause to behave list as a single object. that’s weird and error prone. thanks for your replies.
var result = await _collection.MutateInAsync(userId, builder => { builder.ArrayAppend("permissions", permissions.ToArray()); })
It’s because there are overloads for T
and T[]
- you have to be specific of your intention of T
. You can create a ticket in Jira if you feel its a bug and we’ll look into it or send a PR.
-Jeff