如何让 AllowDBNull 为 GUID 工作?
How can I make AllowDBNull work for GUID?
我正在使用 DataColumn 为 DataTable 创建一个新列。我正在使用 AllowDBNull
指定列可以有 NULL 值。
这很好用,除非我有一个列 uniqueidentifier
我正在做的事情
public static Type GetClrType(SqlDbType sqlType, bool isNullable)
{
switch (sqlType)
{
case SqlDbType.UniqueIdentifier:
return isNullable ? typeof(Guid?) : typeof(Guid);
......other types......
}
}
DataColumn columnValue = DataColumn(column.Name, GetClrType(columnType, IsNullable))
dt.Columns.Add(columnValue);
我在尝试使用 CsvHelper 加载数据表时遇到问题并看到错误
Unhandled exception. System.AggregateException: One or more errors
occurred. (Guid should contain 32 digits with 4 dashes
(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).Couldn't store <NULL>
in
MyGuIdColumn Column. Expected type is Guid.)
感谢任何解决此问题的帮助。
更新(更多细节):
csv文件记录是这样的:
Id (uniqueidentifier, Not null) | Name (Nvarchar, null) | OtherId (uniqueidentifier, null)
deb01846-c208-ec01-a4e4-005056bc1234 | TestName | NULL
我正在这样读取 csv 文件:
var dt = new DataTable();
// get the table def -> will have all column props
foreach (column in columns)
{
var columnType = column.DataType; // (uniqueidentifier) I get this value from table schema
var dataType = Map.GetClrType(columnType); // (GUID) from a SqlDbType -> c# map
DataColumn columnValue = new DataColumn(column.Name, dataType);
columnValue.AllowDBNull = true; // comes from IS Nullable column of table schema
columnValue.DefaultValue = if is nullable => Guid.Empty/Null/DbNUll.Value; // tried these
dt.Columns.Add(columnValue);
}
using (var reader = new StreamReader(filePath))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
using (var dr = new CsvDataReader(csv))
{
dt.Load(dr); // error here
return dt;
}
}
哦..我花了一段时间才看到它,但我怀疑问题是你的 CSV 文件在 OtherId 列中确实包含字符串 "NULL"
;你必须告诉 CSVH “NULL” 意味着 DBNull.Value
以下代码将读取您发布到 github 中的 CSV:
using var reader = new CsvReader(File.OpenText(_openFileDialog.FileName), conf);
using var dataReader = new CsvDataReader(reader);
var dt = dataReader.GetSchemaTable(); //the schema table is huge, get CSVH to make it
//the schema table describes the file layout
dt.Rows[0]["DataType"] = typeof(Guid); //first column is a GUID
dt.Rows[0]["AllowDBNull"] = false; //and not null (default true)
dt.Rows[2]["DataType"] = typeof(Guid); //third column is also a GUID
//tell CSVH that a string of "NULL" is a null value
var tco = new CsvHelper.TypeConversion.TypeConverterOptions();
tco.NullValues.Add("NULL");
reader.Context.TypeConverterOptionsCache.AddOptions<string>(tco);
var ddt = new DataTable();
ddt.Load(dataReader);
现在 ddt 包含一个用于 OtherId 的 Guid 列,它允许空 guids
您不必事先知道列类型。到 var dt = dataReader.GetSchemaTable();var dt = dataReader.GetSchemaTable();
行执行时,dt
将具有列名。如果 headers 与您发布的一样,那么当您获得架构时,但在您读取任何数据之前,您将能够枚举架构 table 并对其进行调整:
ps;我用你的 CSV 作弊了一点,因为我懒得查找如何将管道设置为分隔符 - reader(hah):
的练习
我正在使用 DataColumn 为 DataTable 创建一个新列。我正在使用 AllowDBNull
指定列可以有 NULL 值。
这很好用,除非我有一个列 uniqueidentifier
我正在做的事情
public static Type GetClrType(SqlDbType sqlType, bool isNullable)
{
switch (sqlType)
{
case SqlDbType.UniqueIdentifier:
return isNullable ? typeof(Guid?) : typeof(Guid);
......other types......
}
}
DataColumn columnValue = DataColumn(column.Name, GetClrType(columnType, IsNullable))
dt.Columns.Add(columnValue);
我在尝试使用 CsvHelper 加载数据表时遇到问题并看到错误
Unhandled exception. System.AggregateException: One or more errors occurred. (Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).Couldn't store
<NULL>
in MyGuIdColumn Column. Expected type is Guid.)
感谢任何解决此问题的帮助。
更新(更多细节):
csv文件记录是这样的:
Id (uniqueidentifier, Not null) | Name (Nvarchar, null) | OtherId (uniqueidentifier, null)
deb01846-c208-ec01-a4e4-005056bc1234 | TestName | NULL
我正在这样读取 csv 文件:
var dt = new DataTable();
// get the table def -> will have all column props
foreach (column in columns)
{
var columnType = column.DataType; // (uniqueidentifier) I get this value from table schema
var dataType = Map.GetClrType(columnType); // (GUID) from a SqlDbType -> c# map
DataColumn columnValue = new DataColumn(column.Name, dataType);
columnValue.AllowDBNull = true; // comes from IS Nullable column of table schema
columnValue.DefaultValue = if is nullable => Guid.Empty/Null/DbNUll.Value; // tried these
dt.Columns.Add(columnValue);
}
using (var reader = new StreamReader(filePath))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
using (var dr = new CsvDataReader(csv))
{
dt.Load(dr); // error here
return dt;
}
}
哦..我花了一段时间才看到它,但我怀疑问题是你的 CSV 文件在 OtherId 列中确实包含字符串 "NULL"
;你必须告诉 CSVH “NULL” 意味着 DBNull.Value
以下代码将读取您发布到 github 中的 CSV:
using var reader = new CsvReader(File.OpenText(_openFileDialog.FileName), conf);
using var dataReader = new CsvDataReader(reader);
var dt = dataReader.GetSchemaTable(); //the schema table is huge, get CSVH to make it
//the schema table describes the file layout
dt.Rows[0]["DataType"] = typeof(Guid); //first column is a GUID
dt.Rows[0]["AllowDBNull"] = false; //and not null (default true)
dt.Rows[2]["DataType"] = typeof(Guid); //third column is also a GUID
//tell CSVH that a string of "NULL" is a null value
var tco = new CsvHelper.TypeConversion.TypeConverterOptions();
tco.NullValues.Add("NULL");
reader.Context.TypeConverterOptionsCache.AddOptions<string>(tco);
var ddt = new DataTable();
ddt.Load(dataReader);
现在 ddt 包含一个用于 OtherId 的 Guid 列,它允许空 guids
您不必事先知道列类型。到 var dt = dataReader.GetSchemaTable();var dt = dataReader.GetSchemaTable();
行执行时,dt
将具有列名。如果 headers 与您发布的一样,那么当您获得架构时,但在您读取任何数据之前,您将能够枚举架构 table 并对其进行调整:
ps;我用你的 CSV 作弊了一点,因为我懒得查找如何将管道设置为分隔符 - reader(hah):
的练习