1

I am trying to invoke a sql stored procedure from C#. I have the following code to create the DataColumn. But getting error while createing a DataTable when adding nullable Guid and DateTime type.

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); 

The error is:

DataSet does not support System.Nullable<>. 

Can anyone help me what i am doing wrong here?

I am trying the following:

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); 

Thanks

3
  • Did you try googling the error? The problem is typeof(Guid?) and typeof(DateTime?). By default columns are already nullable. Use typeof(Guid), typeof(DateTime) and typeof(int) instead Commented Apr 13, 2021 at 13:15
  • But getting the error when the value is set. "Data is Null. This method or property cannot be called on Null values." Commented Apr 13, 2021 at 13:25
  • Use DBNull.Value or just null. A DataTable has .NET types like string, int, DateTime, Guid, not povider-specific types Commented Apr 13, 2021 at 13:28

2 Answers 2

5

You have to initialize it with DBNull.Value. But since there is no implicit conversion between your nullable types and that you will produce ugly code. It's better to use the SetField extension method that supports nullables:

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);
Sign up to request clarification or add additional context in comments.

Comments

2

Raw ADO.Net doesn't understand or use Nullable types (it pre-dates them). Instead, you must set (or not) the AllowDBNull property on each DataColumn.

I'd really love to see a hypothetical "ADO.Net v2" that does away with DBNull in favor of Nullable types (and also for DataRow and DataReader to implement the same IDataRecord interface, but that's another story), but I find it unlikely we'll ever see this.

1 Comment

When setting the AlloDBNull , i am getting "Data is Null. This method or property cannot be called on Null values." error

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.