static void

ADO.Net

Connection Strings

Tips

For inserting/updating nullable fields, I use this helper (here as a 3.5 extension method)

internal static class SqlParameterExtensions

{

    //nb instance methods always win over extension methods so you can't add a AddWithValue "overload"

 

    internal static SqlParameter AddWithNullableValue(this SqlParameterCollection col, string parameterName, object value)

    {

        //everything else

        return col.Add(new SqlParameter(parameterName, value ?? DBNull.Value));

    }

}

Concurrency

Paging and Identity

Dataset Trivia

UPSERTs

Doing an insert or update in SQL Server (here the update is just a select to get the identity). The lock hints are important to avoid race problems: see this Sam Saffron post from 2007

private static int Upsert(string naturalKey)
{
    const string sql = @"
DECLARE @Id int = null;
 
IF EXISTS(
    SELECT *
    FROM TestTable WITH (UPDLOCK, SERIALIZABLE)
    WHERE [NaturalKey] = @NaturalKey)
        BEGIN
        SELECT @Id = [Id]
        FROM TestTable
        WHERE [NaturalKey] = @NaturalKey;
        END
ELSE
    BEGIN
        INSERT INTO TestTable 
        ([NaturalKey])
        VALUES
            (@NaturalKey);
    SELECT @Id = CAST(SCOPE_IDENTITY() AS int);
    END
SELECT @Id AS Id";
    int id;
 
    using (var con = new SqlConnection(ConnectionString))
    {
        using (var cmd = new SqlCommand(sql, con))
        {
            cmd.Parameters.AddWithValue("@NaturalKey", naturalKey);
            con.Open();
            id = (int)cmd.ExecuteScalar();
        }
    }
    return id;
}

From SQLServer 2008 you can use the MERGE command, but you still need the lock hints.

private static int Merge(string naturalKey)
{
    const string sql = @"
DECLARE @Id int = null;
 
MERGE INTO TestTable WITH ( HOLDLOCK, SERIALIZABLE ) AS target
    --this is the ...WHERE...
    USING (SELECT @NaturalKey) AS source (NaturalKey)
        ON (target.NaturalKey = source.NaturalKey)
    WHEN MATCHED THEN
        UPDATE SET [LastUpdated] = @LastUpdated
                   ,@Id = [Id] -- cleverly set the id here
    WHEN NOT MATCHED THEN
        INSERT ([NaturalKey],  [LastUpdated] )
            VALUES (@NaturalKey, @LastUpdated);
 
--if id is not set in UPDATE, then grab scope identity
SET @Id = ISNULL(@Id, CAST(SCOPE_IDENTITY() AS int));
 
SELECT @Id AS Id";
    int id;
 
    using (var con = new SqlConnection(ConnectionString))
    {
        using (var cmd = new SqlCommand(sql, con))
        {
            cmd.Parameters.AddWithValue("@NaturalKey", naturalKey);
            cmd.Parameters.AddWithValue("@LastUpdated", DateTime.UtcNow);
            con.Open();
            id = (int)cmd.ExecuteScalar();
        }
    }
    return id;
}