Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: supporting batchquery #3

Merged
merged 1 commit into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ csharp_preserve_single_line_statements = true
csharp_preserve_single_line_blocks = true
csharp_using_directive_placement = outside_namespace:silent
csharp_prefer_simple_using_statement = true
csharp_style_namespace_declarations = block_scoped:silent
csharp_style_namespace_declarations = file_scoped:silent
csharp_style_prefer_method_group_conversion = true
csharp_style_prefer_top_level_statements = true
csharp_style_expression_bodied_lambdas = true
Expand Down
9 changes: 5 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
bin
obj
appsettings.json
coverage
bin
obj
appsettings.json
coverage
node_modules
1 change: 0 additions & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
npx lint-staged
npm test
2 changes: 1 addition & 1 deletion .lintstagedrc.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"*.cs": "npm run lint:fix"
"*.cs": "dotnet format --include"
}
72 changes: 71 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,74 @@ The result sets returned by the method **Query** are IAsyncEnumerable instances
* QueryFirst: To get one result and to throw an error if it's not found;
* QueryFirstOrDefault: To get one result or the default value for the type;

The model passed as a generic parameter for the query methods must be a reference type. You can't use int, bool, or other value types yet, but it can be done in the future.
The model passed as a generic parameter for the query methods must be a reference type. You can't use int, bool, or other value types yet, but it can be done in the future.

# Batch Operations

One of the features offered by this package is batch operation. With that, you can accumulate many sql operations in a single script, run them, and get separated, properly typed results. To do that as showed below:

```c#
// Prepare operations
channel.AddNoScriptResult($"UPDATE MyTable SET Field3 = {myValue} WHERE Id = {myId}");
var itemsHook = channel.QueryHook($"SELECT * FROM MyTable2 WHERE parentId = {myId}");
var singleItemHook = channel.QueryFirstHook($"SELECT TOP 1 * FROM MyTable3 WHERE parentId = {myId}");
var optionalSingleItemHook = channel.QueryFirstOrDefaultHook(@$"SELECT
TOP 1 *
FROM MyTable4
WHERE parentId = {myId}"
);
// Execute all the accumulated operations
await channel.RunQueries();

// Get The desired results
var items = itemsHook.Result;
var singleItem = singleItemHook.Result;
var optionalSingleItem = optionalSingleItemHook.Result;
```

If you want to accumulate many script but don't want to get any results. You can use `Execute` instead of `RunQueries`.
Theare limitations, though, to how many operations can be executed in a single script: the number of parameters. **SqlClient** only support the maximum of 2100 parameters, so, an error will be thrown if you created a script that have more than 2000 parameters. There tools, though, offered to deal seamlessly with that limitation.
The first one is the **PrepareEnumerable**. This method allow you to execute the batching operations
while iterating through an enumerable, and it will run the partial batches before the maximum number of parameters is reached. The only condition is that you don't reach it during the callback. Here's an example of its use:

```c#
await channel.Batch.PrepareEnumerable(pars, async (i, b) =>
{
return b.QueryFirstHook<MyTable>(@$"SELECT *
FROM MyTable
WHERE Id = {i}");
})
// The result if a Enumerable of KeyValue where
// the Key is the input, and the value the result of
// the callback
.ForEachAsync(x => list.Add((x.Key, x.Value.Result)));
```

Notice that parameters passed to the batch method are not interpolated string, but FormattableString.
They're used under the hood to build parameterized queries without the need for you to inform the parameters explicitly.

The second options is the **RunInTransaction** + **AddTransactionScript** methods. This one
servers the purpose of adding persistence operations preferentially in one round trip, but
if the parameter limit is about to be reached, the transaction will be split in many round trips
during the AddTransactionScript call (thus the ValueTask return). Here's an example:

```c#
await channel.RunInTransaction(async () =>
{
await channel.AddTransactionScript(@$"UPDATE MyTable SET
Field1 = {Value1},
Field2 = {Value2},
Field3 = {Value3}
WHERE id = {Id1}");
await channel.AddTransactionScript(@$"UPDATE MyTable2 SET
Field1 = {Value4},
Field2 = {Value5},
Field3 = {Value6}
WHERE id = {Id2}");
await channel.AddTransactionScript(@$"UPDATE MyTable3 SET
Field1 = {Value6},
Field2 = {Value7},
Field3 = {Value8}
WHERE id = {Id3}");
});
```
17 changes: 0 additions & 17 deletions node_modules/.bin/husky

This file was deleted.

17 changes: 0 additions & 17 deletions node_modules/.bin/lint-staged

This file was deleted.

17 changes: 0 additions & 17 deletions node_modules/.bin/node-which

This file was deleted.

17 changes: 0 additions & 17 deletions node_modules/.bin/pidtree

This file was deleted.

17 changes: 0 additions & 17 deletions node_modules/.bin/yaml

This file was deleted.

117 changes: 0 additions & 117 deletions node_modules/.modules.yaml

This file was deleted.

Loading
Loading