表是可以为空的DateTime,但DataSet会抛出异常吗?

问题描述 投票:20回答:9

我正在尝试使用DataSet设计器从查询中创建数据表。我把它弄得很好。使用的查询从数据库返回可为空的datetime列。但是,当它涉及到这段代码时:

DataSet1.DataTable1DataTable table = adapter.GetData();

这会抛出一个StrongTypingException:

[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public System.DateTime event_start_date {
    get {
        try {
            return ((global::System.DateTime)(this[this.tableDataTable1.event_start_dateColumn]));
        }
        catch (global::System.InvalidCastException e) {
            throw new global::System.Data.StrongTypingException("The value for column \'event_start_date\' in table \'DataTable1\' is DBNull.", e);
        }
    }
    set {
        this[this.tableDataTable1.event_start_dateColumn] = value;
    }
}

如何使用设计器允许此列为Nullable?

c# dataset
9个回答
41
投票

类型化数据集不支持可空类型。它们支持可空列。

类型化数据集生成器创建非可空属性以及用于处理空值的相关方法。如果你创建一个MyDate类型和DateTime设置为AllowDbNulltrue列,DataRow子类将实现一个名为DateTime的非可空MyDate属性,一个SetMyDateNull()方法和一个IsMyDateNull()方法。这意味着如果要在代码中使用可空类型,则必须执行以下操作:

DateTime? myDateTime = myRow.IsMyDateNull() ? null : (DateTime?) row.MyDate;

虽然这并没有完全打败使用类型化数据集的目的,但它真的很糟糕。令人沮丧的是,类型化数据集以比System.Data扩展方法更不可用的方式实现可空列。

特别糟糕,因为类型化数据集在某些地方使用可空类型 - 例如,包含上述可为空的DateTime列的表的Add<TableName>Row()方法将采用DateTime?参数。

很久以前,我在MSDN论坛上询问了这个问题,最终ADO项目经理解释说可空类型与类型化数据集同时实现,他的团队没有时间通过​​.NET完全集成这两个类型。 2.0的发货日期。据我所知,从那时起,他们还没有为打字数据集添加新功能。


1
投票

谢谢这解决了我的类似问题:这是代码。在这个问题的情况下

Isevent_start_date()

将返回该字段是否为空。

在我的情况下:我遇到了类似的问题,我使用了以下解决方案

            //Table's Name is Efforts,
            //Column's name is Target
            //So the dataset would automatically generate a property called IsTargetNull() which can be used to check nullables
            //Create an Adaptor
            EffortsTableAdapter ad = new EffortsTableAdapter();
            ProjectDashBoard.Db.EffortsDataTable efforts = ad.GetData();
            DataColumn targetColumn = new DataColumn();
            targetColumn = efforts.TargetColumn;

            List<DateTime?> targetTime = new List<DateTime?>();
            foreach (var item in efforts)
            {

                //----------------------------------------------------
                //This is the line that we are discussing about : 
                DateTime? myDateTime = item.IsTargetNull() ? null : (DateTime?)item.Target;
                //----------------------------------------------------

                targetTime.Add(myDateTime);

            }

1
投票

似乎Designer得到了列错误的数据库类型。

打开xsd Designer,打F4Properties Window打开。选择适当的列并将Nullable(或类似的东西,不记得确切的名称)设置为true。


1
投票

要使这与LINQ一起使用,您必须转到dataset.xsd中的Tables属性。首先查看并确保该列确实设置为可为空。那么你必须查看列的特定属性“NullValue”。 Null Value默认为“Exception”,至少在VS 2012中。对于VB,将其设置为Nothing,这样您就可以在LINQ Where子句中执行“IsNot Nothing”。


1
投票

我这样做是为了在NULL列中插入值DateTime

假设我在数据库中有一个nullable DateTime列,我在一个名为response的对象中从数据库中检索了一些数据,我想在名为nullable DateTime的DataSet列中插入RenewDate值:

// create anew row of the same type of your table row
var rw = ds.StudentActionPrintDT.NewStudentActionPrintDTRow();

// check for null value
if(!response.RenewDate.HasValue)
{
  // if null, then the let DataSet to set it null by it's own way 
  rw.SetRenewDateNull();
}
else
{
  // if not null set value to the datetime value
  rw.RenewDate = response.RenewDate.Value;
}
// add the created row to the dateset [DataSetName].[ColumnName].Add[ColumnName]Row([The Created Row]);
ds.StudentActionPrintDT.AddStudentActionPrintDTRow(rw);

-1
投票

我正在使用下面列出的代码来处理读入数据表的Excel工作表中的空单元格。

if (!reader.IsDBNull(0))                                
{                                    
  row["DateOnCall"] = (DateTime)reader[0];
}

-1
投票

与DataTable和强类型DataTable似乎有所不同......使用像这样。

DataSet1.DataTable1DataTable table = new DataSet1.DataTable1DataTable();
table.Merge(adapter.GetData().CopyToDataTable());

-1
投票

在DataSet Designer中,使用System.Object数据类型而不是System.DateTime并将NullValue设置为(Null),将DefaultValue设置为<DBNull>,并在需要时将其转换为:

var row1 = dateSet1.table1.FirstOrDefault();
if (row1 == null)
    return;
DateTime? date = (DateTime?) row1.ObjectDate;

-2
投票

System.DateTime对象不可为空。要使DateTime可以为空,使其成为DateTime? (在DateTime之后放一个?)

DateTime? nullableDateTime = null;
© www.soinside.com 2019 - 2024. All rights reserved.