### Build the Connector Only Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/README.md Build the Snowflake Connector project. Ensure you have dotnet installed. ```bash cd Snowflake.Data dotnet build --configuration Release ``` -------------------------------- ### Example PowerShell Execution and Output Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/CertficateValidation.md This is an example of running the PowerShell script and its output, showing the extracted certificate information and CRL distribution point URLs for a Snowflake account. ```shell c:\temp>powershell .\checkCrl.ps1 xy12345.us-central1.gcp.snowflakecomputing.com True > Subject: CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1 CRL Distribution Points [1]CRL Distribution Point > Distribution Point Name: Full Name: URL=http://crl3.digicert.com/DigiCertGlobalRootG2.crl > Subject: CN=*.us-central1.gcp.snowflakecomputing.com CRL Distribution Points [1]CRL Distribution Point > Distribution Point Name: Full Name: URL=http://crl3.digicert.com/DigiCertGlobalG2TLSRSASHA2562020CA1-1.crl [2]CRL Distribution Point > Distribution Point Name: Full Name: URL=http://crl4.digicert.com/DigiCertGlobalG2TLSRSASHA2562020CA1-1.crl > Subject: CN=DigiCert Global Root G2 ``` -------------------------------- ### Clone the Source Code Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/README.md Check out the source code from the GitHub repository. Ensure you have git installed. ```bash git clone git@github.com:snowflakedb/snowflake-connector-net snowflake-connector-net ``` -------------------------------- ### Restore Dependencies Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/README.md Navigate to the project directory and restore NuGet packages. Ensure you have nuget installed. ```bash cd snowflake-connector-net nuget restore ``` -------------------------------- ### Install Snowflake.Data via .NET CLI Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/README.md Use this command in the .NET CLI to add the Snowflake.Data package to your project. ```bash dotnet add package Snowflake.Data ``` -------------------------------- ### Install Snowflake.Data via Package Manager Console Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/README.md Use this command in the Package Manager Console to install the Snowflake.Data NuGet package. ```powershell PM> Install-Package Snowflake.Data ``` -------------------------------- ### Arrange, Act, Assert Pattern in Tests Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/CodingConventions.md Structure test code into 'arrange', 'act', and 'assert' blocks when possible. This example demonstrates setting up HttpClient configuration and asserting proxy settings. ```csharp // arrange var config = new HttpClientConfig( true, "snowflake.com", "123", "testUser", "proxyPassword", "localhost", false, false ); // act var handler = (HttpClientHandler) HttpUtil.Instance.SetupCustomHttpHandler(config); // assert Assert.IsTrue(handler.UseProxy); Assert.IsNotNull(handler.Proxy); ``` -------------------------------- ### Expiration Timeout Example Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/ConnectionPooling.md Configures the maximum lifetime of a connection in the pool. Connections exceeding this duration are removed and new ones are created as needed to maintain the minimum pool size. This example sets the expiration timeout to 2 seconds. ```csharp var connectionString = ConnectionString + ";MinPoolSize=1;ExpirationTimeout=2"; var connection1 = new SnowflakeDbConnection(connectionString); var connection2 = new SnowflakeDbConnection(connectionString); var connection3 = new SnowflakeDbConnection(connectionString); connection1.Open(); connection2.Open(); connection1.Close(); connection2.Close(); // 2 connections are in the pool Assert.AreEqual(2, SnowflakeDbConnectionPool.GetPool(connectionString).GetCurrentPoolSize()); Thread.Sleep(2000); connection3.Open(); connection3.Close(); // both previous connections have expired Assert.AreEqual(1, SnowflakeDbConnectionPool.GetPool(connectionString).GetCurrentPoolSize()); ``` -------------------------------- ### Workload Identity Federation Examples Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Connecting.md Connect using Workload Identity Federation, retrieving credentials from cloud platforms (AWS, Azure, GCP) or using a custom OIDC token. ```csharp // AWS using var connAws = new SnowflakeDbConnection("authenticator=workload_identity;workload_identity_provider=aws;account=test;"); ``` ```csharp // Azure (default entra resource) using var connAzure = new SnowflakeDbConnection("authenticator=workload_identity;workload_identity_provider=azure;account=test;"); ``` ```csharp // Azure (custom entra resource) using var connAzureCustom = new SnowflakeDbConnection("authenticator=workload_identity;workload_identity_provider=azure;workload_identity_entra_resource=api://fd3f753b-eed3-462c-b6a7-a4b5bb650aad;account=test;"); ``` ```csharp // GCP using var connGcp = new SnowflakeDbConnection("authenticator=workload_identity;workload_identity_provider=gcp;account=test;"); ``` ```csharp // OIDC (your own token) using var connOidc = new SnowflakeDbConnection("authenticator=workload_identity;workload_identity_provider=oidc;token=yourtoken;account=test;"); ``` -------------------------------- ### Download Stage Files (GET) Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/StageFiles.md This snippet demonstrates how to download files from a Snowflake stage to a local directory. It handles successful downloads and potential SnowflakeDbExceptions, providing the QueryId for troubleshooting. ```cs try { conn.ConnectionString = ""; await conn.OpenAsync(cancellationToken); var cmd = (SnowflakeDbCommand)conn.CreateCommand(); // cast allows get QueryId from the command cmd.CommandText = "GET @my_schema.my_stage/stage_file.csv file://local_file.csv AUTO_COMPRESS=TRUE"; await using var reader = await cmd.ExecuteReaderAsync(cancellationToken); Assert.IsTrue(await reader.ReadAsync(cancellationToken)); // True on success, False if failure Assert.DoesNotThrow(() => Guid.Parse(cmd.GetQueryId())); } catch (SnowflakeDbException e) { Assert.DoesNotThrow(() => Guid.Parse(e.QueryId)); // on failure } ``` -------------------------------- ### Enable or Disable Telemetry via Connection String Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Telemetry.md C# examples demonstrating how to set the `client_telemetry_enabled` parameter in the connection string. Explicitly enabling is the default behavior. ```csharp // Explicitly enable (this is also the default) var connectionString = "account=myaccount;user=myuser;password=mypass;client_telemetry_enabled=true;"; // Explicitly disable var connectionString = "account=myaccount;user=myuser;password=mypass;client_telemetry_enabled=false;"; ``` -------------------------------- ### Execute Query Asynchronously on Server Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/QueryingData.md Start a query to be executed asynchronously on the server. The server responds with a queryId, allowing for status checks and result retrieval later, potentially in a different session. ```cs using var conn = new SnowflakeDbConnection("account=testaccount;username=testusername;password=testpassword") await conn.OpenAsync(CancellationToken.None); SnowflakeDbCommand cmd = (SnowflakeDbCommand)conn.CreateCommand() cmd.CommandText = "SELECT ..."; var queryId = await cmd.ExecuteAsyncInAsyncMode(CancellationToken.None); // ... ``` ```cs var queryStatus = await cmd.GetQueryStatusAsync(queryId, CancellationToken.None); Assert.IsTrue(conn.IsStillRunning(queryStatus)); // assuming that the query is still running Assert.IsFalse(conn.IsAnError(queryStatus)); // assuming that the query has not finished with error ``` ```cs var reader = await cmd.GetResultsFromQueryIdAsync(queryId, CancellationToken.None).ConfigureAwait(false); ``` -------------------------------- ### Get Current Pool Size Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/ConnectionPooling.md Shows how to retrieve the current size of a connection pool. This is useful for verifying pool behavior and settings. ```csharp using var connection = new SnowflakeDbConnection($"{ConnectionString};application=App1") // Pool of size 10 is created var poolSize = SnowflakeDbConnectionPool.GetPool(connectionString).GetCurrentPoolSize(); Assert.AreEqual(10, poolSize); ``` -------------------------------- ### Pool Size Exceeded Timeout Example Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/ConnectionPooling.md Demonstrates the behavior when the pool reaches its maximum size and the waiting timeout expires. An exception is thrown if no idle connections become available within the specified timeout. A value of 0 for WaitingForIdleSessionTimeout causes immediate failure. ```csharp var connectionString = ConnectionString + ";MaxPoolSize=2;WaitingForIdleSessionTimeout=3"; Task[] tasks = new Task[8]; for (int i = 0; i < tasks.Length; i++) { var taskName = $"Task {i}"; tasks[i] = Task.Run(() => { try { using (var connection = new SnowflakeDbConnection(connectionString)) { StopWatch sw = new StopWatch(); // register opening time sw.Start(); connection.Open(); sw.Stop(); // output Console.WriteLine($"{taskName} waited {Math.Round((double)sw.ElapsedMilliseconds / 1000)} seconds"); // wait 2s before closing the connection Thread.Sleep(2000); } } catch (SnowflakeDbException ex) { Console.WriteLine($"{taskName} - {ex.Message}"); } }); } Task.WaitAll(tasks); // check current pool size var poolSize = SnowflakeDbConnectionPool.GetPool(connectionString).GetCurrentPoolSize(); Assert.AreEqual(2, poolSize); // output: // Task 3 waited 0 seconds // Task 0 waited 0 seconds // Task 5 waited 2 seconds // Task 6 waited 2 seconds // Task 4 - Error: Snowflake Internal Error: Unable to connect. Could not obtain a connection from the pool within a given timeout SqlState: 08006, VendorCode: 270001, QueryId: // Task 7 - Error: Snowflake Internal Error: Unable to connect. Could not obtain a connection from the pool within a given timeout SqlState: 08006, VendorCode: 270001, QueryId: // Task 1 - Error: Snowflake Internal Error: Unable to connect. Could not obtain a connection from the pool within a given timeout SqlState: 08006, VendorCode: 270001, QueryId: // Task 2 - Error: Snowflake Internal Error: Unable to connect. Could not obtain a connection from the pool within a given timeout SqlState: 08006, VendorCode: 270001, QueryId: ``` -------------------------------- ### Run Basic Connector Tests Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Library Contributions/Testing.md Execute the connector and tests binaries from the command line. Navigate to the test directory and use the `dotnet test` command with the specified framework. ```bash cd Snowflake.Data.Tests dotnet test -f net10.0 -l "console;verbosity=normal" ``` -------------------------------- ### Sample parameters.json Configuration Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Library Contributions/Testing.md This JSON file configures connection parameters required for running tests against a Snowflake instance. Ensure all sensitive information is replaced with actual test credentials. ```json { "testconnection": { "SNOWFLAKE_TEST_USER": "snowman", "SNOWFLAKE_TEST_PASSWORD": "XXXXXXX", "SNOWFLAKE_TEST_ACCOUNT": "TESTACCOUNT", "SNOWFLAKE_TEST_WAREHOUSE": "TESTWH", "SNOWFLAKE_TEST_DATABASE": "TESTDB", "SNOWFLAKE_TEST_SCHEMA": "TESTSCHEMA", "SNOWFLAKE_TEST_ROLE": "TESTROLE", "SNOWFLAKE_TEST_HOST": "testaccount.snowflakecomputing.com" } } ``` -------------------------------- ### Constructing a Structured Map in SQL Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/StructuredTypes.md Illustrates the SQL syntax for creating a structured map with INTEGER keys and VARCHAR values. ```sql SELECT OBJECT_CONSTRUCT('5','San Mateo', '8', 'CA', '13', '01-234')::MAP(INTEGER, VARCHAR) ``` -------------------------------- ### Create Multiple Connection Pools Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/ConnectionPooling.md Demonstrates how to create separate connection pools by using distinct application names in the connection string. Each pool can have independent settings. ```csharp using var connection = new SnowflakeDbConnection($"{ConnectionString};application=App1") await connection.OpenAsync(cancellationToken); // Pool 1 is created using var connection = new SnowflakeDbConnection($"{ConnectionString};application=App2") await connection.OpenAsync(cancellationToken); // Pool 2 is created ``` -------------------------------- ### Activity with Simple Event Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Telemetry.md Demonstrates creating an activity with a single custom event and a tag. Produces two log entries: one for the activity and one for the explicit event. ```csharp using var activity = command.StartActivity("MyCustomOperation"); activity?.SetTag("app.module", "billing"); activity?.AddTelemetryEvent("ValidationComplete"); activity?.SetSuccess(); ``` ```json [ { "message": { "otel.event.name": "MyCustomOperation", "otel.status_code": "OK", "tag.app.module": "billing", "tag.db.system": "snowflake", "tag.snowflake.session.id": , ... } }, { "message": { "otel.event.name": "ValidationComplete", "otel.status_code": "OK", ... } } ] ``` -------------------------------- ### Verify Snowflake.Data Package Signature Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/README.md Verify the signature of the Snowflake.Data driver package using cosign. Ensure you have cosign installed and have downloaded the package and signature files. ```shell cosign verify-blob snowflake.data.4.2.0.nupkg \ --key snowflake-connector-net-v4.2.0.pub \ --signature Snowflake.Data.4.2.0.nupkg.sig Verified OK ``` -------------------------------- ### Get Current Pool Size Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/ConnectionPooling.md Retrieves the total number of connections (idle, busy, and initializing) in a specific connection pool. The default pool size is 2. ```csharp var pool = SnowflakeDbConnectionPool.GetPool(connectionString); var poolSize = pool.GetCurrentPoolSize(); // default pool size is 2 Assert.AreEqual(2, poolSize); ``` -------------------------------- ### Constructing a Structured Array in SQL Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/StructuredTypes.md Demonstrates the SQL syntax for creating a structured array of TEXT type. ```sql SELECT ARRAY_CONSTRUCT('a', 'b', 'c')::ARRAY(TEXT) ``` -------------------------------- ### Get Total Connection Count Across All Pools Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/ConnectionPooling.md Calculates the total number of connections across all active connection pools. This is useful for monitoring overall resource usage. ```csharp var pool1 = SnowflakeDbConnectionPool.GetPool(connectionString + ";MinPoolSize=2"); var pool2 = SnowflakeDbConnectionPool.GetPool(connectionString + ";MinPoolSize=3"); var poolsSize = SnowflakeDbConnectionPool.GetCurrentPoolSize(); Assert.AreEqual(5, poolsSize); ``` -------------------------------- ### Build .NET Framework Project Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Library Contributions/CodeCoverage.md Builds the Snowflake Connector .NET project for the .NET Framework using MSBuild in Release configuration. ```bash msbuild snowflake-connector-net.sln -p:Configuration=Release ``` -------------------------------- ### Property Naming Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/CodingConventions.md Use PascalCase for properties. ```csharp public ExampleProperty { get; set; } ``` -------------------------------- ### Certificate Revocation Error Example Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/CertficateValidation.md This error occurs when the .NET driver cannot validate a remote certificate due to issues with the certificate chain, such as unknown revocation status or offline revocation. ```csharp error:System.Security.Authentication.AuthenticationException: The remote certificate is invalid because of errors in the certificate chain: RevocationStatusUnknown, OfflineRevocation ``` -------------------------------- ### Build Connector and Test Project Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/README.md Build both the connector and its associated test project. This requires adding a parameters.json file to the Snowflake.Data.Tests directory. ```bash Add a parameters.json file to Snowflake.Data.Tests dotnet build ``` -------------------------------- ### Activity with Multiple Events Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Telemetry.md Shows how to create an activity with multiple explicit events. This results in three log entries: one for the activity and one for each explicit event. ```csharp using var activity = command.StartActivity("MultiStepImport"); activity?.AddTelemetryEvent("StepOneComplete"); activity?.AddTelemetryEvent("StepTwoComplete"); activity?.SetSuccess(); ``` ```json [ { "message": { "otel.event.name": "MultiStepImport", "otel.status_code": "OK", "tag.db.system": "snowflake", "tag.snowflake.session.id": , ... } }, { "message": { "otel.event.name": "StepOneComplete", "otel.status_code": "OK", ... } }, { "message": { "otel.event.name": "StepTwoComplete", "otel.status_code": "OK", ... } } ] ``` -------------------------------- ### Key-Pair Authentication with Encrypted Private Key File Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Connecting.md Establishes a connection using key-pair authentication with an encrypted private key file, requiring the password for decryption. ```csharp using var conn = new SnowflakeDbConnection(); conn.ConnectionString = "account=testaccount;authenticator=snowflake_jwt;user=testuser;private_key_file={pathToThePrivateKeyFile};private_key_pwd={passwordForDecryptingThePrivateKey};db=testdb;schema=testschema"; await conn.OpenAsync(cancellationToken); ``` -------------------------------- ### Extracting CRL Endpoints using OpenSSL and Awk Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/CertficateValidation.md This shell script retrieves the certificate chain for a given Snowflake hostname and extracts the CRL distribution points from each certificate. Ensure openssl and awk are installed on your system. ```shell export hostname="myaccount.eu-central-1.snowflakecomputing.com" echo | openssl s_client -showcerts -connect "$hostname":443 -servername "$hostname" 2>/dev/null | awk '/BEGIN/,/END/{ if(/BEGIN/){a++}; out="cert"a".pem"; print >out}'; for cert in cert*.pem; do echo "--> $cert"; openssl x509 -text -in $cert | awk '/X509v3 CRL Distribution Points/ {print; p=1} /Full Name:/ && p {print; getline; print}' ; echo; done ``` -------------------------------- ### Public Static Member Naming Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/CodingConventions.md Use PascalCase for public static members. ```csharp public class ExampleClass { public static Something SomeVariable; } ``` -------------------------------- ### Connect Using Configuration File Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Connecting.md Open a Snowflake connection without explicitly providing connection string parameters. The driver will automatically read the connection definition from the 'connections.toml' file. ```csharp using var conn = new SnowflakeDbConnection(); await conn.OpenAsync(cancellationToken); // reads connection definition from configuration file ``` -------------------------------- ### Easy Logging Configuration Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Logging.md Configure logging levels and file paths using a JSON file. This is typically used for debugging. ```json { "common": { "log_level": "INFO", "log_path": "c:\\some-path\\some-directory" }, "dotnet": { "log_file_unix_permissions": 640 } } ``` -------------------------------- ### Public Member Naming Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/CodingConventions.md Use PascalCase for public object members. ```csharp public class ExampleClass { public Something SomeVariable; } ``` -------------------------------- ### Password-based Authentication Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Connecting.md Use this snippet for establishing a connection using username and password. Ensure the connection string includes account, user, password, database, and schema details. ```csharp using var conn = new SnowflakeDbConnection(); conn.ConnectionString = "account=testaccount;user=testuser;password=XXXXX;db=testdb;schema=testschema"; await conn.OpenAsync(cancellationToken); ``` -------------------------------- ### Configure Proxy Connection Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Connecting.md Connect through a proxy server by setting proxy-related connection string parameters. Ensure the driver version is 2.0.4 or later. ```csharp using var conn = new SnowflakeDbConnection(); conn.ConnectionString = "account=testaccount;user=testuser;password=XXXXX;db=testdb;schema=testschema;useProxy=true;proxyHost=myproxyserver;proxyPort=8888;proxyUser=test;proxyPassword=test"; await conn.OpenAsync(cancellationToken); ``` -------------------------------- ### Send Custom Telemetry Events with SnowflakeDbCommand Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Telemetry.md C# code for creating and sending custom telemetry events using the `StartActivity` extension method on `SnowflakeDbCommand`. Requires an open connection with telemetry enabled. ```csharp using System.Diagnostics; using Snowflake.Data.Client; using Snowflake.Data.Telemetry; using var connection = new SnowflakeDbConnection("account=myaccount;user=myuser;password=mypass;"); connection.Open(); using var command = (SnowflakeDbCommand)connection.CreateCommand(); // Start a custom activity — requires an open connection with telemetry enabled using var activity = command.StartActivity("MyCustomOperation"); // Add your own tags activity?.SetTag("app.module", "billing"); activity?.SetTag("app.batch_size", "500"); // Add named events within the activity activity?.AddTelemetryEvent("ValidationComplete"); // Add events with tags activity?.AddTelemetryEvent("BatchProcessed", new KeyValuePair("batch.size", 500), new KeyValuePair("batch.duration_ms", 1234)); // On success: activity?.SetSuccess(); // Or on failure: // activity?.SetException(exception); ``` -------------------------------- ### Reading a Structured Map in C# Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/StructuredTypes.md Demonstrates how to read a structured map from a SnowflakeDbDataReader using GetMap. ```csharp var reader = (SnowflakeDbDataReader) command.ExecuteReader(); Assert.IsTrue(reader.Read()); var map = reader.GetMap(0); ``` -------------------------------- ### Run Integration Tests by Namespace Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Library Contributions/Testing.md Execute only the integration tests by specifying the namespace. This is useful for testing the connector's integration with Snowflake services. ```bash cd Snowflake.Data.Tests dotnet test -l "console;verbosity=normal" -namespace "Snowflake.Data.Tests.IntegrationTests" ``` -------------------------------- ### Key-Pair Authentication with Private Key File Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Connecting.md Connects to Snowflake using key-pair authentication by specifying the path to an unencrypted private key file. ```csharp using var conn = new SnowflakeDbConnection(); conn.ConnectionString = "account=testaccount;authenticator=snowflake_jwt;user=testuser;private_key_file={pathToThePrivateKeyFile};db=testdb;schema=testschema"; await conn.OpenAsync(cancellationToken); ``` -------------------------------- ### Build .NET 6 Project for Coverage Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Library Contributions/CodeCoverage.md Builds the Snowflake Connector .NET project for the .NET 6 framework with debug symbols enabled for code coverage. ```bash dotnet build snowflake-connector-net.sln /p:DebugType=Full ``` -------------------------------- ### Key-Pair Authentication with Private Key Content Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Connecting.md Connects using key-pair authentication by providing the unencrypted private key content directly in the connection string. ```csharp var privateKeyContent = File.ReadAllText(pathToThePrivateKeyFile); using var conn = new SnowflakeDbConnection(); conn.ConnectionString = $"account=testaccount;authenticator=snowflake_jwt;user=testuser;private_key={privateKeyContent};db=testdb;schema=testschema"; await conn.OpenAsync(cancellationToken); ``` -------------------------------- ### Upload Local Files to Stage (PUT) Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/StageFiles.md Use this snippet to upload local files to a Snowflake stage. Ensure the connection string and stage details are correctly configured. Exceptions like FileNotFoundException may occur if the local file does not exist. ```cs using var conn = new SnowflakeDbConnection(); try { conn.ConnectionString = ""; await conn.OpenAsync(cancellationToken); var cmd = (SnowflakeDbCommand)conn.CreateCommand(); // cast allows get QueryId from the command cmd.CommandText = "PUT file://some_data.csv @my_schema.my_stage AUTO_COMPRESS=TRUE"; await using var reader = await cmd.ExecuteReaderAsync(cancellationToken); Assert.IsTrue(await reader.ReadAsync(cancellationToken)); Assert.DoesNotThrow(() => Guid.Parse(cmd.GetQueryId())); } catch (SnowflakeDbException e) { Assert.DoesNotThrow(() => Guid.Parse(e.QueryId)); // when failed Assert.That(e.InnerException.GetType(), Is.EqualTo(typeof(FileNotFoundException))); } ``` -------------------------------- ### Clean and Clear NuGet Cache Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Library Contributions/CodeCoverage.md Cleans the .NET solution and clears the local NuGet package cache. Run this before building. ```bash dotnet clean snowflake-connector-net.sln && dotnet nuget locals all --clear ``` -------------------------------- ### Activity with No Explicit Events Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Telemetry.md Illustrates creating an activity without any explicit telemetry events. Only a single synthetic activity event is produced. ```csharp using var activity = command.StartActivity("SimpleQuery"); activity?.SetSuccess(); ``` ```json { "message": { "otel.event.name": "SimpleQuery", "otel.status_code": "OK", "tag.db.system": "snowflake", "tag.snowflake.session.id": , ... } } ``` -------------------------------- ### Use File-Based Credential Manager Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Cache.md Enables the file-based implementation for storing credentials. This is the least secure option and stores credentials in a JSON file. ```cs SnowflakeCredentialManagerFactory.UseFileCredentialManager(); ``` -------------------------------- ### Run Unit Tests by Namespace Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Library Contributions/Testing.md Execute only the unit tests by specifying the namespace. This helps in isolating and running a specific set of tests. ```bash cd Snowflake.Data.Tests dotnet test -l "console;verbosity=normal" -namespace "Snowflake.Data.Tests.UnitTests" -l console;verbosity=normal ``` -------------------------------- ### Native SSO through Okta Connection Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Connecting.md Establish a connection using native SSO via Okta. The connection string requires the Okta account endpoint URL and the IdP login name. ```csharp using var conn = new SnowflakeDbConnection(); conn.ConnectionString = "account=testaccount;authenticator={okta_url_endpoint};user={login_name_for_IdP};db=testdb;schema=testschema"; await conn.OpenAsync(cancellationToken); ``` -------------------------------- ### Executing Multiple SQL Statements in a Batch Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/QueryingData.md This C# code demonstrates executing a batch of three SQL statements. It first sets the MULTI_STATEMENT_COUNT session parameter and then configures a command with the MULTI_STATEMENT_COUNT statement parameter set to 3, followed by the SQL commands. ```cs using var conn = new SnowflakeDbConnection() conn.ConnectionString = ConnectionString; await conn.OpenAsync(cancellationToken); var cmd = conn.CreateCommand(); cmd.CommandText = "ALTER SESSION SET MULTI_STATEMENT_COUNT = 1"; await cmd.ExecuteNonQueryAsync(cancellationToken); using var cmd2 = conn.CreateCommand(); // Set statement count var stmtCountParam = cmd2.CreateParameter(); stmtCountParam.ParameterName = "MULTI_STATEMENT_COUNT"; stmtCountParam.DbType = DbType.Int16; stmtCountParam.Value = 3; cmd2.Parameters.Add(stmtCountParam); cmd2.CommandText = "CREATE OR REPLACE TABLE test(n int);INSERT INTO test values(1), (2); SELECT * FROM test ORDER BY n;" await using var reader = await cmd2.ExecuteReaderAsync(cancellationToken); do { if (reader.HasRow) { while (await reader.ReadAsync(cancellationToken)) { // read data } } } while (reader.NextResult()); ``` -------------------------------- ### Connection String with Equal Sign Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Connecting.md Demonstrates how to include an equal sign (=) in the password. Prior to version 2.0.18, a double equal sign was required for escaping. ```csharp var connectionString = "account=testaccount;user=testuser;password=test=password;"; ``` -------------------------------- ### Class Naming for Interface Implementation Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/CodingConventions.md Use the 'Snowflake' prefix for classes that implement standard interfaces, such as 'SnowflakeDbCommand' extending 'DbCommand' and implementing 'IDbCommand'. ```csharp public class SnowflakeDbCommand : DbCommand { } ``` -------------------------------- ### Method Naming Convention Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/CodingConventions.md Use PascalCase for all method names, including normal, object members, static members, public, internal, and private methods. ```csharp void SomeMethod() { } ``` -------------------------------- ### Programmatic Access Token with Connection String Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Connecting.md Authenticate using a programmatic access token generated for your user. The token is supplied directly within the connection string. ```csharp using var conn = new SnowflakeDbConnection(); conn.ConnectionString = "account=testaccount;user=testuser;db=testdb;schema=testschema;authenticator=programmatic_access_token;token=testtoken"; await conn.OpenAsync(cancellationToken); ``` -------------------------------- ### Collect Code Coverage for .NET Framework (GCP) Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Library Contributions/CodeCoverage.md Collects code coverage for the .NET Framework build targeting GCP. Requires a parameters.json file in Snowflake.Data.Tests and a coverage.config file. ```bash dotnet-coverage collect "dotnet test --framework net472 --no-build -l console;verbosity=normal" --output net472_GCP_coverage.xml --output-format cobertura --settings coverage.config ``` -------------------------------- ### Reading an Object into a C# Class Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/StructuredTypes.md Execute a SQL command and read the resulting object into a C# class instance using `SnowflakeDbReader.GetObject`. ```csharp var reader = (SnowflakeDbDataReader) command.ExecuteReader(); Assert.IsTrue(reader.Read()); var address = reader.GetObject
(0); ``` -------------------------------- ### Limit Maximum Pool Size Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/ConnectionPooling.md Demonstrates how to limit the total number of connections in the pool. New connection requests will wait if the maximum is reached, and an exception is thrown if the timeout is exceeded. ```csharp var connectionString = ConnectionString + ";MaxPoolSize=2"; Task[] tasks = new Task[8]; for (int i = 0; i < tasks.Length; i++) { var taskName = $"Task {i}"; tasks[i] = Task.Run(() => { using (var connection = new SnowflakeDbConnection(connectionString)) { StopWatch sw = new StopWatch(); // register opening time sw.Start(); connection.Open(); sw.Stop(); // output Console.WriteLine($"{taskName} waited {Math.Round((double)sw.ElapsedMilliseconds / 1000)} seconds"); // wait 2s before closing the connection Thread.Sleep(2000); } }); } Task.WaitAll(tasks); // check current pool size var poolSize = SnowflakeDbConnectionPool.GetPool(connectionString).GetCurrentPoolSize(); Assert.AreEqual(2, poolSize); // output: // Task 1 waited 0 seconds // Task 4 waited 0 seconds // Task 7 waited 2 seconds // Task 0 waited 2 seconds // Task 6 waited 4 seconds // Task 3 waited 4 seconds // Task 2 waited 6 seconds // Task 5 waited 6 seconds ``` -------------------------------- ### Failed Activity with Exception Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Telemetry.md Demonstrates creating an activity that fails and includes an exception. This generates two log entries: the synthetic activity event and an event for the exception. ```csharp using var activity = command.StartActivity("FailedOp"); activity?.SetException(new InvalidOperationException("something broke")); ``` ```json [ { "message": { "otel.event.name": "FailedOp", "otel.status_code": "ERROR", "tag.status.code": "ERROR", "tag.db.system": "snowflake", ... } }, { "message": { "otel.event.name": "exception", "otel.status_code": "ERROR", "tag.exception": "System.InvalidOperationException", ... } } ] ``` -------------------------------- ### Run a Query and Read Data Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/QueryingData.md Execute a SQL query and iterate through the results using a data reader. Note that TIME columns are returned as System.DateTime, and TimeSpan can be obtained via GetTimeSpan on SnowflakeDbDataReader. ```cs using var conn = new SnowflakeDbConnection(); conn.ConnectionString = connectionString; await conn.OpenAsync(cancellationToken); var cmd = conn.CreateCommand(); cmd.CommandText = "select * from t"; await using var reader = await cmd.ExecuteReaderAsync(cancellationToken); while(await reader.ReadAsync(cancellationToken)) { Console.WriteLine(reader.GetString(0)); } await conn.CloseAsync(cancellationToken); ``` ```cs TimeSpan timeSpanTime = ((SnowflakeDbDataReader)reader).GetTimeSpan(13); ``` -------------------------------- ### Use In-Memory Credential Manager Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Cache.md Enables the in-memory implementation for storing credentials. This is the most secure option and persists within the application's runtime. ```cs SnowflakeCredentialManagerFactory.UseInMemoryCredentialManager(); ``` -------------------------------- ### Test Connection Pool Clean - Snowflake .NET Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/ConnectionPoolingDeprecated.md Demonstrates how to manage and monitor the size of a single connection pool by adding and closing connections. Note that some configurations available for multiple connection pools are not applicable here. ```cs public void TestConnectionPoolClean() { SnowflakeDbConnectionPool.ClearAllPools(); SnowflakeDbConnectionPool.SetMaxPoolSize(2); var conn1 = new SnowflakeDbConnection(); conn1.ConnectionString = ConnectionString; conn1.Open(); Assert.AreEqual(ConnectionState.Open, conn1.State); var conn2 = new SnowflakeDbConnection(); conn2.ConnectionString = ConnectionString + " retryCount=1"; conn2.Open(); Assert.AreEqual(ConnectionState.Open, conn2.State); Assert.AreEqual(0, SnowflakeDbConnectionPool.GetCurrentPoolSize()); conn1.Close(); conn2.Close(); Assert.AreEqual(2, SnowflakeDbConnectionPool.GetCurrentPoolSize()); var conn3 = new SnowflakeDbConnection(); conn3.ConnectionString = ConnectionString + " retryCount=2"; conn3.Open(); Assert.AreEqual(ConnectionState.Open, conn3.State); var conn4 = new SnowflakeDbConnection(); conn4.ConnectionString = ConnectionString + " retryCount=3"; conn4.Open(); Assert.AreEqual(ConnectionState.Open, conn4.State); conn3.Close(); Assert.AreEqual(2, SnowflakeDbConnectionPool.GetCurrentPoolSize()); conn4.Close(); Assert.AreEqual(2, SnowflakeDbConnectionPool.GetCurrentPoolSize()); Assert.AreEqual(ConnectionState.Closed, conn1.State); Assert.AreEqual(ConnectionState.Closed, conn2.State); Assert.AreEqual(ConnectionState.Closed, conn3.State); Assert.AreEqual(ConnectionState.Closed, conn4.State); } ``` -------------------------------- ### Connection String with Double Quote Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Connecting.md Shows how to include a double quote (") in the password. The connection string builder handles escaping. ```csharp var connectionString = "account=testaccount;user=testuser;password=test\"password;"; ``` -------------------------------- ### Configure Telemetry Flush Behavior Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Telemetry.md Customize the telemetry module's buffering and flushing behavior by setting the flush size threshold and the periodic flush interval. These settings are global and apply to sessions created after the configuration. ```csharp using Snowflake.Data.Telemetry; // Set the number of buffered activities that triggers an automatic flush (default: 100) SessionTelemetryModuleFacade.SetFlushSize(50); // Set the periodic flush interval in milliseconds (default: 60000 ms / 1 minute) SessionTelemetryModuleFacade.SetFlushInterval(30_000); ``` -------------------------------- ### Collect Code Coverage for .NET Framework (Azure) Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Library Contributions/CodeCoverage.md Collects code coverage for the .NET Framework build targeting Azure. Requires a parameters.json file in Snowflake.Data.Tests and a coverage.config file. ```bash dotnet-coverage collect "dotnet test --framework net472 --no-build -l console;verbosity=normal" --output net472_AZURE_coverage.xml --output-format cobertura --settings coverage.config ``` -------------------------------- ### Connection String with Single Quote Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Connecting.md Demonstrates how to include a single quote (') in the password when using password-based authentication. The connection string builder handles escaping. ```csharp var connectionString = "account=testaccount;user=testuser;password=test'password;"; ``` -------------------------------- ### Collect Code Coverage for .NET 6 (GCP) Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Library Contributions/CodeCoverage.md Collects code coverage for the .NET 6 build targeting GCP. Requires a parameters.json file in Snowflake.Data.Tests and a coverage.config file. ```bash dotnet-coverage collect "dotnet test --framework net6.0 --no-build -l console;verbosity=normal" --output net6.0_GCP_coverage.xml --output-format cobertura --settings coverage.config ``` -------------------------------- ### Annotating Class for Constructor Construction Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/StructuredTypes.md Use the `[SnowflakeObject]` annotation with `CONSTRUCTOR` to enable object construction via a constructor. The constructor must have parameters matching the number and order of database object fields. ```csharp [SnowflakeObject(ConstructionMethod = SnowflakeObjectConstructionMethod.CONSTRUCTOR)] public class Address { private string _city; private string _state; public Address() { } public Address(string city, string state) { _city = city; _state = state; } } ``` -------------------------------- ### Class Naming for Non-Interface Implementation Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/CodingConventions.md Do not use any particular prefix for classes that do not implement standard interfaces. ```csharp public class FastParser { } ``` -------------------------------- ### Set Permissions for connections.toml Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Connecting.md On Mac/Linux, ensure the connections.toml file has restricted permissions for security. This command sets ownership and read/write permissions for the file owner. ```bash chown $USER connections.toml chmod 0600 connections.toml ``` -------------------------------- ### Binding Array as JSON for Stored Procedures Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/QueryingData.md Demonstrates how to pass local arrays to stored procedures by serializing them to JSON and using `PARSE_JSON(?)`. This method is required as direct array binding is not supported. ```cs using Snowflake.Data; using Newtonsoft.Json; .. using var cmd = conn.CreateCommand(); var vals = new int[] { 1, 2, 3 }; var array = JsonConvert.SerializeObject(vals); // alternatively you can do `vals.ToArray()` when passing it to `p1.Value` var sql = "CALL test_db.public.test(parse_json(?))"; // test SP, returns a single value // execute this sql with bind variable 'array' cmd.CommandText = sql; var p1 = cmd.CreateParameter(); p1.ParameterName = "1"; p1.Value = array; // passing the array in thebind variable. p1.DbType = DbType.String; cmd.Parameters.Add(p1); await using reader = cmd.ExecuteReaderAsync(cancellationToken); while (await reader.ReadAsync(cancellationToken)) { Console.WriteLine(reader.GetString(0)); } await conn.CloseAsync(cancellationToken); ``` -------------------------------- ### Configure OpenTelemetry Tracer Provider Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Telemetry.md When using the OpenTelemetry SDK, ensure your tracer provider is configured to include the custom activity source name. This allows OpenTelemetry to capture spans from the Snowflake connector. ```csharp using OpenTelemetry; using OpenTelemetry.Trace; var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddSource(ActivityStarter.CustomSourceName) // "Client_custom_activity" .AddConsoleExporter() .Build(); ``` -------------------------------- ### Interface Naming Convention Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/CodingConventions.md Prefix interface names with 'I' (without an 'Interface' postfix). ```csharp interface IName { } ``` -------------------------------- ### Collect Code Coverage for .NET Framework (AWS) Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Library Contributions/CodeCoverage.md Collects code coverage for the .NET Framework build using dotnet-coverage. Requires a parameters.json file in Snowflake.Data.Tests and a coverage.config file. ```bash dotnet-coverage collect "dotnet test --framework net472 --no-build -l console;verbosity=normal" --output net472_AWS_coverage.xml --output-format cobertura --settings coverage.config ``` -------------------------------- ### Listen to Custom Activities Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Telemetry.md Implement an ActivityListener to capture and process custom telemetry events. This listener filters for activities originating from `ActivityStarter.CustomSourceName` and logs details when an activity stops. ```csharp using System.Diagnostics; using Snowflake.Data.Telemetry; var listener = new ActivityListener { ShouldListenTo = source => source.Name == ActivityStarter.CustomSourceName, Sample = (ref ActivityCreationOptions _) => ActivitySamplingResult.AllData, ActivityStopped = activity => { Console.WriteLine($"Activity: {activity.OperationName}"); Console.WriteLine($" Duration: {activity.Duration.TotalMilliseconds}ms"); Console.WriteLine($" Session: {activity.GetTagItem(TelemetryTags.SessionId)}"); Console.WriteLine($" Status: {activity.GetTagItem(TelemetryTags.StatusCode)}"); } }; ActivitySource.AddActivityListener(listener); ``` -------------------------------- ### Define Connection in TOML File Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Connecting.md Store connection parameters in a TOML file for easier management. The driver automatically reads this file from standard locations or a path specified by SNOWFLAKE_HOME. ```toml [myconnection] account = "myaccount" user = "jdoe" password = "xyz1234" ``` -------------------------------- ### Changed Session Behavior: OriginalPool Mode Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/ConnectionPooling.md Demonstrates the 'OriginalPool' mode for changed sessions. Altered connections are returned to their original pool, but may have different session contexts (database, schema, warehouse, role) than the connection string specifies. ```csharp var connectionString = ConnectionString + ";ChangedSession=OriginalPool;MinPoolSize=1;MaxPoolSize=1"; var connection = new SnowflakeDbConnection(connectionString); connection.Open(); var randomSchemaName = Guid.NewGuid(); connection.CreateCommand($"create schema \"{randomSchemaName}\"").ExecuteNonQuery(); // schema is changed connection.Close(); // connection returns to the pool with the altered schema var connection2 = new SnowflakeDbConnection(connectionString); connection2.Open(); // operations execute against randomSchemaName, not the schema in ConnectionString ``` -------------------------------- ### Use Windows Credential Manager Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Cache.md Enables the Windows Credential Manager for storing credentials. This is a secure option that leverages built-in Windows capabilities. ```cs SnowflakeCredentialManagerFactory.UseWindowsCredentialManager(); ``` -------------------------------- ### Activity with Detailed Events and Tags Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Telemetry.md Shows an activity with multiple explicit events, each having its own tags, and activity-level tags. Produces four log entries: the synthetic activity event and one for each explicit event. ```csharp using var activity = command.StartActivity("MyCustomOperationWithEvents"); activity?.SetTag("app.module", "billing_extra"); activity?.AddTelemetryEvent("ValidationStarted", new KeyValuePair("Mode", "Basic")); activity?.AddTelemetryEvent("ValidationConfirmed", new Dictionary { ["Mode"] = "Advanced", ["ConfirmedBy"] = "John" }); activity?.AddTelemetryEvent("ValidationComplete"); activity?.SetSuccess(); ``` ```json { "message": { "otel.event.name": "MyCustomOperationWithEvents", "otel.status_code": "OK", "tag.app.module": "billing_extra", "tag.db.system": "snowflake", ... } } { "message": { "otel.event.name": "ValidationStarted", "otel.status_code": "OK", "tag.Mode": "Basic", ... } } { "message": { "otel.event.name": "ValidationConfirmed", "otel.status_code": "OK", "tag.Mode": "Advanced", "tag.ConfirmedBy": "John", ... } } { "message": { "otel.event.name": "ValidationComplete", "otel.status_code": "OK", ... } } ``` -------------------------------- ### Programmatic Access Token with Secure Property Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Connecting.md Provide the programmatic access token as a secure property instead of including it in the connection string for enhanced security. ```csharp using var conn = new SnowflakeDbConnection("connection-string-without-token"); conn.Token = ...; // configure token here await conn.OpenAsync(cancellationToken); ``` -------------------------------- ### Set Custom Credential Manager Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Cache.md Allows users to implement and set their own custom credential manager. Replace 'CustomCredentialManagerImplementation' with your custom class. ```cs SnowflakeCredentialManagerFactory.SetCredentialManager(CustomCredentialManagerImplementation); ``` -------------------------------- ### Test Method Naming Convention Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/CodingConventions.md Use PascalCase for test method names, avoiding MS-proposed underline characters between logical parts of the test name. ```csharp [Test] public void TestThatLoginWithInvalidPasswordFails() { } [Test] public void TestCreatingHttpClientHandlerWithProxy() { } ``` -------------------------------- ### Browser-based SSO Connection Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Connecting.md Initiate a connection using browser-based Single Sign-On. The `externalbrowser` authenticator is used, and optionally a specific user can be specified. ```csharp using var conn = new SnowflakeDbConnection(); conn.ConnectionString = "account=testaccount;authenticator=externalbrowser;user={login_name_for_IdP};db=testdb;schema=testschema"; await conn.OpenAsync(cancellationToken); ``` -------------------------------- ### Collect Code Coverage for .NET 6 (Azure) Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Library Contributions/CodeCoverage.md Collects code coverage for the .NET 6 build targeting Azure. Requires a parameters.json file in Snowflake.Data.Tests and a coverage.config file. ```bash dotnet-coverage collect "dotnet test --framework net6.0 --no-build -l console;verbosity=normal" --output net6.0_AZURE_coverage.xml --output-format cobertura --settings coverage.config ``` -------------------------------- ### Constructing and Casting an Object in SQL Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/StructuredTypes.md Use `OBJECT_CONSTRUCT` to create a structured object in SQL and cast it to a specific object type with defined column types. ```sql SELECT OBJECT_CONSTRUCT('city','San Mateo', 'state', 'CA')::OBJECT(city VARCHAR, state VARCHAR) ``` -------------------------------- ### Internal or Private Member Naming Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/CodingConventions.md Use the '_' prefix followed by camelCase for internal or private object members. ```csharp public class ExampleClass { private Something _someVariable; internal Something _someInternalVariable; } ``` -------------------------------- ### Connection String with Double-Quoted Identifiers Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/Connecting.md Shows how to use double-quoted identifiers for object property values like DATABASE, allowing for case sensitivity and special characters. ```csharp var connectionString = "account=testaccount;db=\"testDB\";"; ``` -------------------------------- ### Local Variable Naming Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/CodingConventions.md Use camelCase for local variables. ```csharp { Something someVariable; } ``` -------------------------------- ### Annotating Class for Properties Names Construction Source: https://github.com/snowflakedb/snowflake-connector-net/blob/master/doc/Client/StructuredTypes.md Use the `[SnowflakeObject]` annotation with `PROPERTIES_NAMES` to enable object construction based on property names. Database field names must match C# property names, or `[SnowflakeColumn(Name = ...)]` must be used. ```csharp [SnowflakeObject(ConstructionMethod = SnowflakeObjectConstructionMethod.PROPERTIES_NAMES)] public class Address { [SnowflakeColumn(Name = "nearestCity")] public string city { get; set; } public string state { get; set; } public Zip zip { get; set; } } ```