简体   繁体   中英

NPGSQL Copy nullable Value

I'm trying to insert some data into a Postgres Database via the Copy-Statement.

This a part of the code:

            await using var writer =
                await connection.BeginBinaryImportAsync(
                    "COPY \"SomeTable\" (\"NormalLong\", \"NullableLong\") FROM STDIN (FORMAT BINARY)");

            foreach (var t in batch)
            {
                await writer.StartRowAsync();
                await writer.WriteAsync(t.NormalLong, NpgsqlDbType.BigInt);
                await writer.WriteAsync(t.NullableLong, NpgsqlDbType.Bigint);
            }
public class SampleClass {
  public long NormalLong { get; set; }
  public long? NullableLong { get; set; }
}

At the time of execution, both Values on t are set to some numeric value, but the Value of Type long? always results in this error:

System.NullReferenceException: Object reference not set to an instance of an object.

Is there a way to deal with this, without changing the Type, since it sometimes needs to be null?

While the solution provided by CKK works, it results in a warning in my IDE, which would be ok.

I went with another solution and write a helper class which contains the following code for each data-type I need:

    public static async Task WriteAsync(NpgsqlBinaryImporter writer, long value, NpgsqlDbType type)
    {
        await writer.WriteAsync(value, type);
    }

    public static async Task WriteAsync(NpgsqlBinaryImporter writer, long? value, NpgsqlDbType type)
    {
        if (value.HasValue) await writer.WriteAsync(value.Value, type);
        else await writer.WriteNullAsync();
    }

Try this

public static void WriteNullable<T>(this NpgsqlBinaryImporter writer, T? obj, NpgsqlDbType type)
    where T : class
{
    if (obj is null)
    {
        writer.WriteNull();
    }
    else
    {
        writer.Write(obj, type);
    }
}

public static void WriteNullable<T>(this NpgsqlBinaryImporter writer, T? obj, NpgsqlDbType type)
    where T : struct
{
    if (obj.HasValue)
    {
        writer.Write(obj.Value, type);
    }
    else
    {
        writer.WriteNull();
    }
}

Use

NpgsqlBinaryImporter writer = ...;
writer.WriteNullable("some text", NpgsqlDbType.Text);
long? value1 = 12;
long? value2 = null;
writer.WriteNullable(value1, NpgsqlDbType.Bigint);
writer.WriteNullable(value2, NpgsqlDbType.Bigint);

Also you can adapt it to async/await.
Works for .NET5

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM