Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何解析来自数据库datareader的值并处理可能的空值?_C#_Vb.net_Null_Types - Fatal编程技术网

C# 如何解析来自数据库datareader的值并处理可能的空值?

C# 如何解析来自数据库datareader的值并处理可能的空值?,c#,vb.net,null,types,C#,Vb.net,Null,Types,这个问题我已经遇到过好几次了,从来没有找到一个好的答案。我想其他人一定已经处理好了 我有一个从数据库返回的datareader,我想使用其中的值,但是值可能包含空值,也可能不包含空值。我希望有一个helper函数,它接收来自datareader的值,如果该值不为NULL,则返回该值,如果为NULL,则返回空白 我的问题是,我正在测试的变量的数据类型是变量。它可以是字符串、整数或日期时间。有谁能建议一种简单的方法来测试该值,然后返回原始值(如果可能的话,返回相同的数据类型)或者如果该值为空的话返回

这个问题我已经遇到过好几次了,从来没有找到一个好的答案。我想其他人一定已经处理好了

我有一个从数据库返回的datareader,我想使用其中的值,但是值可能包含空值,也可能不包含空值。我希望有一个helper函数,它接收来自datareader的值,如果该值不为NULL,则返回该值,如果为NULL,则返回空白

我的问题是,我正在测试的变量的数据类型是变量。它可以是字符串、整数或日期时间。有谁能建议一种简单的方法来测试该值,然后返回原始值(如果可能的话,返回相同的数据类型)或者如果该值为空的话返回其他值


目前我正在使用VB.NET,但我也想知道如何在C#中实现这一点。谢谢。

您可以使用
IDataReader.IsDBNull
方法检查数据库中的字段是否为空。

我相信这适用于大多数情况(我没有测试过):

public parset值(System.Data.SqlClient.SqlDataReader读取器,字符串列)
{
T结果=默认值(T);
if(!reader.IsDBNull(reader.GetOrdinal(列)))
结果=(T)reader.GetValue(reader.GetOrdinal(列));
返回结果;
}
如果该类型为
null

int v=dr.GetValue(“vvv”);/,则返回该类型的默认值如果列为null,则抛出
int v = dr.GetValue<int>("vvv");             // throws if column is null
int? w = dr.GetValue<int?>("www");           // set to null if column is null
int x = dr.GetValue<int?>("xxx") ?? -1;      // set to -1 if column is null
string y = dr.GetValue<string>("yyy");       // set to null if column is null
string z = dr.GetValue<string>("zzz") ?? ""  // set to "" if column is null

// ...

public static T GetValue<T>(this IDataRecord source, string fieldName)
{
    return source.GetValue<T>(source.GetOrdinal(fieldName));
}

public static T GetValue<T>(this IDataRecord source, int fieldIndex)
{
    if (source == null)
        throw new ArgumentNullException("source");

    if (fieldIndex < 0)
        throw new ArgumentOutOfRangeException("fieldIndex", fieldIndex,
                                              "Index cannot be negative.");

    if (source.IsDBNull(fieldIndex))
    {
        T defaultValue = default(T);
        if (defaultValue == null)
            return defaultValue;
    }

    // throws if the field is null and T is a non-nullable value type
    return (T)source.GetValue(fieldIndex);
}
智力?w=dr.GetValue(“www”);//如果列为null,则设置为null int x=dr.GetValue(“xxx”)-1; // 如果列为空,则设置为-1 字符串y=dr.GetValue(“yyy”);//如果列为null,则设置为null 字符串z=dr.GetValue(“zzz”)??“”//如果列为空,则设置为“” // ... 公共静态T GetValue(此IDataRecord源,字符串字段名) { 返回source.GetValue(source.GetOrdinal(fieldName)); } 公共静态T GetValue(此IDataRecord源,int fieldIndex) { if(source==null) 抛出新的ArgumentNullException(“源”); 如果(字段索引<0) 抛出新ArgumentOutOfRangeException(“fieldIndex”,fieldIndex, “索引不能为负。”); if(source.IsDBNull(fieldIndex)) { T defaultValue=默认值(T); if(defaultValue==null) 返回默认值; } //如果字段为null且T是不可为null的值类型,则引发 返回(T)source.GetValue(fieldIndex); }
我使用一个扩展方法,它接受一个对象、预期/最终类型和默认值。如果对象为null(或DBNull),则返回默认值。如果对象可以转换为最终/预期类型,则会执行转换并返回强类型对象。如果转换失败,它将返回一个默认值或根据您是否严格而引发异常。下面是该方法的外观-

    /// <summary>
    /// Gets the non null value.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="item">The item.</param>
    /// <param name="defaultValue">The default value.</param>
    /// <param name="strict">if set to <c>true</c> [strict].</param>
    /// <returns></returns>
    [DebuggerStepThrough]
    public static T GetNonNullValue<T>(this object item, T defaultValue, bool strict) {
        if(item.IsNullOrEmpty() || item == DBNull.Value) {
            return defaultValue;
        }

        var originalType = item.GetType();
        var targetType = typeof(T);

        if(originalType == targetType || originalType.IsSubclassOf(targetType)) {
            return (T)item;
        }

        TypeConverter typeConverter = TypeDescriptor.GetConverter(targetType);
        if(typeConverter.CanConvertFrom(originalType)) {
            return (T)typeConverter.ConvertFrom(item);
        }

        typeConverter = TypeDescriptor.GetConverter(originalType);
        if(typeConverter.CanConvertTo(targetType)) {
            return (T)typeConverter.ConvertTo(item, targetType);
        }

        if(strict) {
            throw new QIGException("Conversion from {0} to {1} failed!", originalType, targetType);
        }

        return defaultValue;
    }
//
///获取非空值。
/// 
/// 
///这个项目。
///默认值。
///如果设置为true[严格]。
/// 
[调试步骤至]
公共静态T GetNonNullValue(此对象项,T defaultValue,bool strict){
if(item.IsNullOrEmpty()| | item==DBNull.Value){
返回默认值;
}
var originalType=item.GetType();
var targetType=typeof(T);
if(originalType==targetType | | originalType.IsSubclassOf(targetType)){
退货(T)项;
}
TypeConverter-TypeConverter=TypeDescriptor.GetConverter(targetType);
if(类型转换器.CanConvertFrom(原始类型)){
返回(T)类型转换器。转换源(项目);
}
typeConverter=TypeDescriptor.GetConverter(originalType);
if(typeConverter.CanConvertTo(targetType)){
return(T)typeConverter.ConvertTo(item,targetType);
}
如果(严格){
抛出新的QigeException(“从{0}到{1}的转换失败!”,originalType,targetType);
}
返回默认值;
}
编辑1: 为了澄清这一点,您可以将其与数据读取器一起使用,如下所示-

        SqlDataReader dr = GetResultsIntoDataReader();
        string column1Value = dr["ColumnName1"].GetNonNullValue(String.Empty);
        int? column2Value = dr["ColumnName2"].GetNonNullValue(new Nullable<int>());
        double column3Value = dr["ColumnName3"].GetNonNullValue(0.0);
SqlDataReader dr=getresultintodatareader();
string column1Value=dr[“ColumnName1”].GetNonNullValue(string.Empty);
智力?column2Value=dr[“ColumnName2”].GetNonNullValue(新的Nullable());
double column3Value=dr[“ColumnName3”]。GetNonNullValue(0.0);

我发现w69rdy的答案不适用于SQL货币类型或数字。我试着用它把钱转换成浮动和双倍。两者都不起作用。我将我的货币类型转换为数字(18,4),但它仍然不会转换为浮动或双精度

在所有情况下,它都会引发类型强制转换异常

不过,我确实得到了YetAnotherUser的答案,只做了一些小改动

必须改变:

if(item.IsNullOrEmpty() || item == DBNull.Value)

抛出新的QigeException(“从{0}到{1}的转换失败!”,originalType,targetType)

还增加了:

public static T GetNonNullValue<T>(this object item, T defaultValue)
{
    return item.GetNonNullValue(defaultValue, true);
}
不是


我还读了一些关于自定义扩展的文章,但是他们很酷。我将不得不进一步探索它们。

我喜欢这个。简单而有效。现在我只需要把它转换成VB.NET。@webworm好极了,让我知道你是如何使用它的。还要注意我刚刚做的更新,我稍微简化了它,并修复了一个检查其是否为null的错误(我一直在使用一个自定义读取器,它允许您通过名称检查列是否为null,但SqlDataReader需要一个索引)
if(item == null || item == DBNull.Value) **
throw new Exception(string.Format("Conversion from {0} to {1} failed!", originalType, targetType));
public static T GetNonNullValue<T>(this object item, T defaultValue)
{
    return item.GetNonNullValue(defaultValue, true);
}
curInsurance.Pharmacy = dataReader["Pharmacy"].GetNonNullValue(-1d);
curInsurance.Pharmacy = dataReader["Pharmacy"].GetNonNullValue(-1d, true);