C# Sql ADO.Net DataColumn 添加可为空的 Guid 列时出错

C# Sql ADO.Net DataColumn error adding nullable Guid column

我正在尝试从 C# 调用 sql 存储过程。我有以下代码来创建 DataColumn。但是在添加可为 null 的 Guid 和 DateTime 类型时创建 DataTable 时出错。

DataTable dt = new DataTable();
        dt.Columns.AddRange(new DataColumn[]
        {
            new DataColumn(nameof(LearnerEntity.FirstName), typeof(string)),
            new DataColumn(nameof(LearnerEntity.DateOfBirth), typeof(DateTime?)),
            new DataColumn(nameof(LearnerEmployerEntity.SectorId), typeof(Guid?)),
            new DataColumn(nameof(LearnerEntity.EPortfolioId), typeof(int?))
        });
        dt.Rows.Add(
            learnerEntity.FirstName,
            learnerEntity.DateOfBirth ?? SqlDateTime.Null,
            learnerEntity.Employer?.SectorId ?? SqlGuid.Null.Value,
            learnerEntity.EPortfolioId ?? SqlInt32.Null.Value); 

错误是:

DataSet does not support System.Nullable<>. 

任何人都可以帮助我我做错了什么吗?

我正在尝试以下操作:

DataTable dt = new DataTable();
        dt.Columns.AddRange(new DataColumn[]
        {
            new DataColumn(nameof(LearnerEntity.FirstName), typeof(string)),
            new DataColumn(nameof(LearnerEntity.DateOfBirth), Nullable.GetUnderlyingType(typeof(LearnerEmployerEntity).GetProperty("DateOfBirth").PropertyType)),
            new DataColumn(nameof(LearnerEmployerEntity.SectorId), Nullable.GetUnderlyingType(typeof(LearnerEmployerEntity).GetProperty("SectorId").PropertyType)),
            new DataColumn(nameof(LearnerEntity.EPortfolioId), Nullable.GetUnderlyingType(typeof(LearnerEmployerEntity).GetProperty("EPortfolioId").PropertyType))
        });
        dt.Rows.Add(
            learnerEntity.FirstName,
            learnerEntity.DateOfBirth ?? SqlDateTime.Null,
            learnerEntity.Employer?.SectorId ?? SqlGuid.Null.Value,
            learnerEntity.EPortfolioId ?? SqlInt32.Null.Value); 

谢谢

Raw ADO.Net 不理解或不使用 Nullable 类型(它早于它们)。相反,您必须在每个 DataColumn 上设置(或不设置)AllowDBNull 属性。

我真的 喜欢 看到一个假设的“ADO.Net v2”,它取消了 DBNull 以支持可空类型(以及 DataRow 和 DataReader 实现相同的 IDataRecord 接口,但这是另一回事),但我发现我们不太可能看到这一点。

您必须用 DBNull.Value 初始化它。但是由于您的可空类型之间没有隐式转换,因此您将产生难看的代码。最好使用支持 nullables 的 SetField 扩展方法:

DataRow row = dt.Rows.Add();
row.SetField<string>(nameof(LearnerEntity.FirstName), LearnerEntity.FirstName);
row.SetField<DateTime?>(nameof(LearnerEntity.DateOfBirth), LearnerEntity.DateOfBirth);
row.SetField<Guid?>(nameof(LearnerEmployerEntity.SectorId), learnerEntity.Employer?.SectorId);
row.SetField<int?>(nameof(LearnerEntity.EPortfolioId), LearnerEntity.EPortfolioId);