NPGSQL 复制可为空的值
NPGSQL Copy nullable Value
我正在尝试通过复制语句将一些数据插入 Postgres 数据库。
这部分代码:
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; }
}
在执行时,t
上的两个值都设置为某个数值,但类型 long?
的值总是导致此错误:
System.NullReferenceException: Object reference not set to an instance of an object.
有没有办法在不更改类型的情况下处理这个问题,因为它有时需要为空?
虽然 CKK 提供的解决方案有效,但它会在我的 IDE 中产生警告,这没关系。
我采用了另一种解决方案并编写了一个助手 class,其中包含我需要的每种数据类型的以下代码:
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();
}
试试这个
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();
}
}
使用
NpgsqlBinaryImporter writer = ...;
writer.WriteNullable("some text", NpgsqlDbType.Text);
long? value1 = 12;
long? value2 = null;
writer.WriteNullable(value1, NpgsqlDbType.Bigint);
writer.WriteNullable(value2, NpgsqlDbType.Bigint);
您也可以将其调整为 async/await。
适用于 .NET5
我正在尝试通过复制语句将一些数据插入 Postgres 数据库。
这部分代码:
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; }
}
在执行时,t
上的两个值都设置为某个数值,但类型 long?
的值总是导致此错误:
System.NullReferenceException: Object reference not set to an instance of an object.
有没有办法在不更改类型的情况下处理这个问题,因为它有时需要为空?
虽然 CKK 提供的解决方案有效,但它会在我的 IDE 中产生警告,这没关系。
我采用了另一种解决方案并编写了一个助手 class,其中包含我需要的每种数据类型的以下代码:
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();
}
试试这个
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();
}
}
使用
NpgsqlBinaryImporter writer = ...;
writer.WriteNullable("some text", NpgsqlDbType.Text);
long? value1 = 12;
long? value2 = null;
writer.WriteNullable(value1, NpgsqlDbType.Bigint);
writer.WriteNullable(value2, NpgsqlDbType.Bigint);
您也可以将其调整为 async/await。
适用于 .NET5