c# OracleDataAdapter.Fill 遇到不支持的 Oracle 数据类型

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c# OracleDataAdapter.Fill 遇到不支持的 Oracle 数据类型相关的知识,希望对你有一定的参考价值。

我的环境是VS2010 /.NET4.0/ Oracle11g Client , 服务器端Oracle10g

我是想通过程序向多种数据库自动生成数据, 我先是实现了SQLServer的操作,最近添加了对Oracle的功能。
首先我是通过GetSchema得到数据库中表的结构,
然后通过结构中的表名,用SQL 的Select语句取得表的内容,
并将数据库中所有表保存在DataSet中

下面是我的代码
foreach (DataRow row in databaseSchemaTable.Rows)

string tableName = row["TABLE_NAME"].ToString();
string sql = string.Format("SELECT * FROM 0", tableName);
try

IDbDataAdapter dbAdp = dbFactory.CreateDataAdapter(sql, dbConn);
dbFactory.Fill(dbAdp, ds, tableName);

catch (Exception ex)

logger.Error(string.Format("0表取得失败。", tableName), ex);




这里当取Oracle其中的一个表时,总是报” 遇到不支持的 Oracle 数据类型 ”、
我想问如何解决这个错误。和为什么会出错?
并且,我只管向数据库中已有的表中生成数据,并不管数据库中表的结构,那么如何避免这个错误的生成?

多谢高手解答!
dbFactory.Fill(dbAdp, ds, tableName);
是自己封装的代码里面就是返回了 OracleDataAdapter.Fill(collectionName, restrictionValues


在网上看到这样的回答
-------------
主要是字段为空间字段,如用SDO_GEOMETRY存储方式就oracle会有自定义的MDSYS.SDO_GEOMETRY字段类型,使用 OracleCommand不支持这种字段类型。不过咱们使用SQL的目的是得到属性数据,可以过滤掉空间字段等。
--------------
感觉说的有理,那么如何过滤掉空间字段呢

参考技术A BINARY_DOUBLE、BINARY_FLOAT类型可以导致这个错误

C#进阶C# 泛型

序号系列文章
17【C#进阶】C# 委托
18【C#进阶】C# 事件
19【C#进阶】C# 集合类

文章目录

前言

🎫 hello大家好啊,我是哈桑c,本文为大家介绍 C# 中的泛型。


1、泛型的概念

泛型允许延迟指定一个或多个变量的类型。泛型指的是类或其它数据类型在定义时不会指定类中的属性或方法参数的具体类型,而是在实例化类对象时再确定参数的具体类型。

以一个程序示例展示泛型的基本用法,并借此讨论泛型的使用。

代码示例

using System;
using System.Collections.Generic;

public class MyGenericList<T>

    private List<T> myList;

    public MyGenericList()
    
        myList = new List<T>  ;
    

    // 增加元素
    public void AddElement(T value)
    
        myList.Add(value);
    

    // 删除元素
    public void RemoveElement(T value)
    
        myList.Remove(value);
    
    
    // 更改元素
    public void SetElement(int index, T value)
    
        myList[index] = value;
    

    // 查找元素
    public T GetElement(int index)
    
        return myList[index];
    


public class Program

    static void Main(string[] args)
    
        MyGenericList<int> list = new MyGenericList<int>  ; 
        
        for(int e = 0; e < 10; e++)
            list.AddElement(e);

        Console.WriteLine("list列表中的元素有:");
        for (int i = 0; i < 10; i++)
            Console.WriteLine(list.GetElement(i));
    

运行结果:


在上面的示例中,类中出现的每个 T 在运行时均会被替换为 int 类型参数。 通过这种替换,我们就可以通过单个泛型定义来确定类中四个增删改查方法中的参数类型,并成功输出 int 类型的列表变量。

2、泛型的使用

在 C# 中,只要涉及到使用类型参数的地方基本都可以使用泛型。泛型常用于类、方法、接口和委托等等。适当的使用泛型有利于提高代码的灵活性、重用性等。

2.1、类型参数的命名

关于类型参数的命名官方的建议可以总结为以下四点:

  • 和参数命名一样,请使用描述性名称命名泛型类型参数,除非单个字母名称完全具有自我说明性且描述性名称不会增加任何作用
public interface ISessionChannel<TSession>  /*...*/ 
  • 对具有单个字母类型参数的类型,习惯使用 T 作为类型参数名称。
public class MyGenericList<T>
  • 在类型参数描述性名称前添加前缀 “T”。
public interface ISessionChannel<TSession>

    TSession Session  get; 

  • 请考虑在参数名称中指示出类型参数的约束。 例如,约束为 ISession 的参数可命名为 TSession。
// 泛型T被约束为ISession
public T MySession(T TSession)/*...*/ 

接下里介绍泛型常见的几个用法:

2.2、泛型类

泛型类表示类中有一个或多个参数的类型为泛型。泛型类最常见用法是用于链接列表、哈希表、堆栈、队列和数等集合。而且无论存储数据的类型如何,在数据操作方面等执行方式都基本相同。

通常创建泛型类是从现有具体类开始,然后每次逐个将类型更改为类型参数,直到泛化和可用性达到最佳平衡。同时创建泛型类需要注意以下四点:

  • 选择需要泛化的类型参数:通常可泛化的类型越多,代码就越灵活、可重用性就越高。但过度泛化会导致代码可读性变低。
  • 是否使用泛型约束:合理的使用泛型类型参数约束,可防止数据类型的误用。
  • 实现一个或多个泛型接口:泛型可用于接口,如果需要实现在泛型的集合中创建项的类,则可以创建一个或多个泛型接口。
  • 是否将泛型行为分解为基类和子类:泛型类可用作基类,但是泛型类作为基类或子类需要遵循一定的继承规则。

代码示例:(泛型类的继承行为)、

泛型类可继承自具体的封闭式构造或开放式构造基类:

class BaseNode  
class BaseNodeGeneric<T>  

// 具体类型
class NodeConcrete<T> : BaseNode  

// 封闭构造类型 
class NodeClosed<T> : BaseNodeGeneric<int>  

// 开放构造类型 
class NodeOpen<T> : BaseNodeGeneric<T>  

非泛型类不可继承自开放式构造类或类型参数,因为运行时无法提供基类所需的类型参数。

// 没有问题
class Node1 : BaseNodeGeneric<int>  

// 产生 CS0246 编译错误
//class Node2 : BaseNodeGeneric<T>  

点击了解更多泛型类的继承行为。

2.3、泛型接口

泛型接口表示接口中有一个或多个参数的类型为泛型。 使用泛型接口有很多好处,例如可以避免对值类型执行装箱和取消装箱操作。 当一组表示抽象规范的接口需要针对多种类型时就可以使用泛型接口。

代码示例:

// 具体类可实现封闭式构造接口 

// 基础接口 
interface IBaseInterface<T>

    public T MyMethod(T value);


// 实现接口的方法
class SampleClass : IBaseInterface<int>

    // 实现接口中的方法
    public int MyMethod(int value)
    
        return value;
    
 

适用于类的继承规则也适用于接口:

interface IMonth<T>  

interface IJanuary : IMonth<int>    //没有错误
interface IFebruary<T> : IMonth<int>    //没有错误
interface IMarch<T> : IMonth<T>      //没有错误

//interface IApril<T> : IMonth<T, U>    // 编译错误 CS0305

2.4、泛型方法

泛型方法表示方法中有一个或多个参数的类型为泛型。在前面的示例中,我们已经使用了泛型类,可以在泛型类中顺利通过类型声明泛型方法。当一组操作针对多种类型参数时需要使用泛型方法。

代码示例:

using System;
using System.Collections.Generic;

public class SamplesGenericMethod

    static void Main(string[] args)
    
        int a = 10;
        int b = 20;

        Swap<int>(ref a, ref b);
        Console.WriteLine($"交换之后的a和b的值分别为ab");
    

    static void Swap<T>(ref T lhs, ref T rhs)
    
        T temp;
        temp = lhs;
        lhs = rhs;
        rhs = temp;
     

运行结果

2.5、泛型委托

不仅是在方法和类,委托也可以定义它自己的类型参数。泛型委托表示在定义中使用泛型代替具体类型的委托。引用泛型委托的代码可以指定类型参数以创建封闭式构造类型,同时也可以不指定具体类型参数创建开放式构造类型。当一组引用类型需要封装多种类型方法时就可以使用泛型委托。

代码示例:

public class SamplesGenericDelegate
 
    public delegate void Del<T>(T item);

    public static void Notify(int i) 
    
        Console.WriteLine($"使用了泛型委托,并接受了整数参数i");
    

    static void Main(string[] args)
    
        Del<int> m1 = Notify;
        m1(11); 
    

运行结果:

3、泛型参数的约束

泛型约束就是告知编译器类型参数必须具备的功能。 在没有任何约束的情况下,类型参数可以是任何类型。 编译器只能假定 System.Object 的成员,它是任何 .NET 类型的最终基类。当分配给泛型的类型参数不满足约束的类型时,编译器会报出 Compiler Error CS0452 的错误。在 C# 中允许使用 where 上下文关键字指定约束。

3.1、值类型约束

where T : struct 表示类型参数必须是不可为 null 的值类型。

这里的示例代码记得改类名

代码示例:

// 值类型约束
public class MyGenericList<T> where T : struct

	// 类成员... 

由于所有值类型都具有可访问的无参数构造函数,因此 struct 约束也表示 new() 约束,所以 struct 约束不能与 new() 约束和 unmanaged 约束一起使用。

3.2、引用类型约束

where T : class 表示类型参数必须是的引用类型。

代码示例:

// 引用类型约束
public class MyGenericList<T> where T : class

	// 类成员... 

此约束还应用于任何类、接口、委托或数组类型。 在可为 null 的上下文中,T 必须是不可为 null 的引用类型。

泛型约束的介绍独立出一篇文章来了点击了解更多泛型约束的使用。

4、泛型的特性总结

在 C# 中泛型是一种增强程序功能的技术,具体体现为以下几点:

  • 泛型的好处: 正确地使用泛型可以提高代码的可读性、重用性以及灵活性,可以在一定程度上提高程序的性能。
  • 泛型的坏处: 错误或者过度地使用泛型容易导致类型异常、使代码变得复杂(可读性变低)以及很难确定参数真正的类型等问题。
  • 用途广泛: 除了文中提到泛型的用法之外,还可以创建自定义的泛型数组、泛型事件以及泛型和反射的结合等。
  • 泛型集合类:.NET 框架在 System.Collections.Generic 命名空间中提供了泛型集合类,其中包含用于定义泛型集合的接口和类,可允许用户创建强类型集合,以提供比非泛型强类型集合更好的类型安全性和性能。

点击了解更多泛型的使用。


结语

⛽️ 以上就是 C# 泛型的介绍啦,希望对大家有所帮助。感谢大家的支持。

以上是关于c# OracleDataAdapter.Fill 遇到不支持的 Oracle 数据类型的主要内容,如果未能解决你的问题,请参考以下文章

OracleDataAdapter.Fill 抛出“SQL 命令未正确结束”

从 OracleDataAdapter.Fill() 填充 DataTable 时“指定的转换无效”

在 oracle sql developer 中加入查询快,在 odp.net 中超慢

C#入门系列——第一个C#程序

译《C# 小技巧 -- 编写更优雅的 C#》原书名《C# Tips -- Write Better C#》

C#进阶C# 泛型