且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

即使检查查询正确后,我的表适配器也返回null

更新时间:2022-12-03 12:04:06

这很奇怪;您已经拥有所有类型都具有正确类型属性的强类型数据行,但是您将它们视为具有字符串列名称的通用数据行,其中包含要进行tostring()和解析的对象.从未打算以这种方式使用它.

This is wonky; you've got strongly typed data rows with proper typed properties for everything, yet you're treating them as generic datarows with string column names, holding objects that you're tostring()ing and parsing. It was never intended to be used this way.

您的代码应更像这样:

    ViewMedia viewMediaSetInstance = new ViewMedia();
    ViewMedia.ViewMediaDataTable viewMediaTable = new ViewMedia.ViewMediaDataTable();
    Model.ViewMediaTableAdapters.ViewMediaTableAdapter MediaTableAdapter = new Model.ViewMediaTableAdapters.ViewMediaTableAdapter();

    MediaTableAdapter.findByPublishYear(viewMediaTable, publishYear);

    //don't need to access the .Rows property to get the count
    if (viewMediaTable.Count > 0)
    {
        //don't need to access the .Rows property to get the data
        ViewMediaRow selectedUser = viewMediaTable[0];
        media = new Media(selectedUser.MediaID, selectedUser.Title, selectedUser.PublishYear);
        return media;
    }
    else
    {
        return null;
    }

我也不同意您在 datatable.Rows.Count 为null的代码注释中的断言.数据表的 .Count 属性是整数,而不管使用的是强类型还是弱类型的数据表.它永远不能为空

I also disagree with your assertion in the code comments that datatable.Rows.Count is null. A datatable's .Count property is an integer regardless of whether a strongly or weakly typed datatable is in use; it can never be null

如果启用创建返回数据表的方法,则无需创建数据集.通常,这些方法称为 GetDataByXXX ,填充方法称为 FillByXXX (您已将填充方法称为findByPublishYear).它是在TA向导的以下屏幕上配置的:

You don't need to create a dataset, if you enable creating a method that returns a datatable. Typically these methods are called GetDataByXXX and the fill methods are called FillByXXX (you've called your fill method findByPublishYear). It's configured on the following screen of the TA wizard:

图片由nullskull.com提供

这可以将您的代码简化为以下代码(添加对Model.ViewMediaTableAdapters的引用):

This can simplify your code to just the following (add a reference to Model.ViewMediaTableAdapters):

    var mDT = new ViewMediaTableAdapter().GetDataByPublishYear(publishYear);

    Media m = null;
    if (mDT.Count > 0)
        media = new Media(mDT[0].MediaID, mDT[0].Title, mDT[0].PublishYear);

    return m;

最关键的是,不要通过 .Rows 集合( viewMediaDataTable.Rows [0] )访问第一行,因为返回基本类型 DataRow .通过强类型数据表( viewMediaDataTable [0] )上的默认属性索引器直接访问它,因为这将返回ViewMediaRow类型的对象,而该对象又为所有列中的名称都很好地命名,键入了属性数据表

Most critically here, DON'T access the first row via the .Rows collection (viewMediaDataTable.Rows[0]) because that returns a base type DataRow. Access it directly via the default property indexer on the strongly typed datatable (viewMediaDataTable[0]) as this will return an object of type ViewMediaRow which in turn has nicely named, typed properties for all the columns in the datatable

viewMediaDataTable[0].PublishYear; //ViewMediaRow is a strongly typed class that has this property as an int
viewMediaDataTable.Rows[0].PublishYear; //"DataRow does not contain a definition for 'PublishYear'"

现在,如果该行中的任何数据项为null,并且该列在null上的设置为引发异常",您将看到类型为

Now, if any of the data items in the row is null and the setting of the column upon null is "throw exception" you will see an exception of type StrongTypingException- it happens when you have some column that is of a type that cannot be null (such as an int) but it's null because the database query didn't return a value for that row. You were hitting this with your code because som int column (for example) was DBNull.Value and the only thing a datarow will do whn you try to access an int column tha tis DBNull, is throw an exception. By specifying SELECT * in the query, you caused the query to return a value for the column; by not selecting a column the datatable will always treat it as null. You can still also encounter a strongtypingexception if the value of the data in the database is also null. In these cases, use the IsXXXNull() methods to determine if the property is null before trying to access it (causing a strongtypingexception)