item.Name=dataReader.GetString(dataReader.GetOrdinal ("proName"));

本文详细介绍了用于操作数据库的代码实现,包括配置文件的使用、数据连接字符串的编写、类中ToString方法的重载、COMBOX下拉列表的展示、数据集与数据库的交互以及SQL查询语句的应用。
www.programfan.com
用于操作左边数据库的代码
放在Main()方法下面
static void Main()
{
  string dataDir=AppDomain.CurrentDomain.BaseDirectory;
  if(dataDir.EndsWith(@"\bin\Debug\")
    ||dataDir.EndsWith(@"\bin\Release\"))
   {
      dataDir=System.IO.Directory.GetParent(dataDir).Parent.Parent.FullName;
      AppDomain.CurentDomain.SetData("DataDirectory",dataDir);
   }


将连接数据库字符串写到配置文件(新建项-配置文件)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <connectionStrings>
    <add name="ConnStr" connetionString="Data Source=**;DataBase=**;pwd=***;uid=***">
  </connectionStrings>
</configuration>

//引用  添加引用
system.configuration;

/*************************
类中ToString 方法是调用基类的ToString(), 在类中重载ToString方法。
public override string ToString()
{
  return name;
}

combox  DisplayMember 属性 设置
using(SqlConnection conn=new SqlConnection(string strConn)
{
   conn.Open();
   using (SqlCommand cmd=conn.CreateCommand())
{
  cmd.CommandText="select * from city where proID=@proID";
  cmd.Parameters.Add=(new SqlParameter("proID",proID));
  using (SqlDataReader dataReader=cmd.ExecuteReader())
  {
    string cityName=dataReader.GetString(dataReader.GetOrdinal("cityName"));
    cmbCity.items.Add("cityName");
}


using(SqlConnection conn=new SqlConnection(string strConn)
{
   conn.Open();
   using (SqlCommand cmd=conn.CreateCommand())
{
  cmd.CommandText="select * from city where proID=@proID";
  cmd.Parameters.Add=(new SqlParameter("proID",proID));
  using (SqlDataReader dataReader=cmd.ExecuteReader())
  {
         while(dataReader.Read())
          {

            ProvinceItem item=new ProvinceItem();
            item.ID=dataReader.GetInt32(dataReader.GetOrdinal              ("proID"));
            item.Name=dataReader.GetString(dataReader.GetOrdinal           ("proName"));
           //添加到COMBOX下拉列表
            cmbPro.Items.Add(item);
           }
}


// dataset 中更新数据到数据库0

SqlCommandBuilder builder=new SqlCommandBuilder(adapter);
adapter.Update(dataset);


Data Source=(LocalDB)\v12.0;AttachDbFilename="E:\Visual Studio 2013\Projects\ADO.DB\WindowsFormsApplication1\Database12.mdf";Integrated Security=True

// 创建数据库 删除数据库表  删除数据

Create Table T_yuangong(id int not null, name nvarchar(10),age int null)
drop table T_yuangong
delete from T_yuangong where Age<18
SQL : ddl(数据定义语言)Create Table\ Drop Table  dml(数据操作语言)insert into 、 select* from Table where..... 、delete、update

//条件查询
select * from T_Employee Where FName like '_ry‘
select * from T_Employee Where FName like '%n%‘
select * from T_Employee Where FName is(not) null
select * from T_Employee Where FName in(Tim,Tom)
select * from T_Employee Where FName between 20 and 50
select * from T_Employee Where FAge>=20 and FAge<50

//分组查询 (聚合函数是不能放到Where 子句中的)
select FAge,Count(*) from T_Employee group by FAge

select FAge,Count(*) from T_Employee group by FAge having count(*)>2
// 查询语句的函数
ceiling 舍到最大 floor 舍到最小  round 四舍五入  ABS()绝对值
LTRIM,RTRIM ,LTRIM(RTRIM()),DATEADD,DATEDIFF

类型转换
cast  convert
//添加 列

select FNumber,
sum(
  case
  when FAmount>0 than FAmount
  else 0
end
)as 收入
sum(
   case
   when FAmount<0 than ABS(FAmount)
   else 0
end
 )as 支出
from T_Amount

select Name,
sum(
 case Score
 when N'胜' than 1
 else 0
 end
)as 胜
sum(
 case Score
 when N'负' than 1
 else 0
 end
)as 负
from T_Score
group by Name

//强数据类型
批量操作之前 先将adapter打开,然后再关闭,这样可以提升效率
adapter.Connection.Open();
……………………………………
adapter.Connection.Close();
  
<think>我们正在解释一个C#方法:GetReportData,它属于GetDataForEDI类。该方法的功能是从Oracle数据库中获取报告数据。 输入参数:InputRecord record,包含查询条件(如日期范围、客户ID列表、客户名称等) 返回值:List<OutputRecord>,即输出记录列表。 根据代码逻辑,该方法的主要步骤如下: 1. 建立Oracle数据库连接。 2. 创建一个OracleCommand对象,设置命令类型为存储过程(CommandType.StoredProcedure),并指定存储过程名称为"PKG_TEST_API.GET_DATA_FOR_EDI_NEW"。 3. 添加多个Oracle参数,这些参数对应存储过程的输入参数: - V_TEST_END_DATE_FROM(日期) - V_TEST_END_DATE_TO(日期) - V_CUSTOMER_NUMBER(整数数组,使用OracleDbType.Array) - V_KEY_CLIENT(字符串) 4. 执行存储过程,并获取一个OracleDataReader对象。 5. 将OracleDataReader的内容读取到一个DataTable中。 6. 关闭连接。 7. 将DataTable转换为List<OutputRecord>(通过DataTableToList方法)。 8. 返回这个列表。 注意:其中使用了Oracle.DataAccess.Client(ODP.NET)来操作Oracle数据库。 另外,在参数传递中,对于数组类型的参数(V_CUSTOMER_NUMBER),代码中使用了OracleCommand的Parameters.Add方法,并指定了OracleDbType.Array,同时设置了一个OracleParameter的属性(UdtTypeName)为"ARRAY_NUMBER"(一个自定义的数组类型)。 这里需要特别注意的是,数组参数的处理需要数据库中存在对应的数组类型(ARRAY_NUMBER)。在Oracle中,这通常是通过CREATE TYPE语句创建的类型。 现在,我们按照步骤详细解释代码: 步骤1:连接字符串从配置文件中获取(通过GetConnectionString方法,但此方法在代码片段中未给出)。 步骤2:设置OracleCommand对象,并添加参数。其中,数组参数的处理如下: - 如果传入的客户ID列表(record.CUSTOMER_NUMBER)不为空且数量大于0,则创建一个整数数组(int[]),并将其作为参数值。 - 否则,设置参数值为DBNull.Value。 步骤3:使用OracleDataAdapter将OracleDataReader填充到DataTable中。 步骤4:调用DataTableToList方法将DataTable转换为List<OutputRecord>。该方法使用反射机制,将DataTable的每一行转换为OutputRecord对象。转换时,将行中的每个单元格(列)的值赋给OutputRecord对象的同名属性。 步骤5:返回结果。 现在,我们用中文解释代码逻辑: 1. 建立数据库连接:使用连接字符串创建OracleConnection。 2. 创建命令对象,设置为存储过程,并指定存储过程名称。 3. 添加参数: - 添加两个日期参数(V_TEST_END_DATE_FROMV_TEST_END_DATE_TO),值来自record对象。 - 添加一个数组参数(V_CUSTOMER_NUMBER):如果record中的客户ID列表不为空,则转换为int数组,否则为DBNull。 - 添加一个字符串参数(V_KEY_CLIENT),值为record.KEY_CLIENT(可能为空)。 4. 执行存储过程,并用DataReader读取数据。 5.DataReader的数据填充到DataTable。 6. 关闭连接。 7. 将DataTable的每一行转换为OutputRecord对象(通过反射遍历属性并赋值)。 8. 返回OutputRecord的列表。 注意:异常处理在调用该方法的上层(即ExportLimsData方法)已经包含,所以该方法本身没有try-catch块。 下面,我们根据要求生成相关问题。 相关问题: 1. 在C#中如何使用ODP.NET调用Oracle存储过程? 2. 如何将DataTable转换为强类型对象列表? 3. 在Oracle数据库中如何创建使用数组类型(如ARRAY_NUMBER)? 4. 使用反射将DataRow转换为对象时需要注意哪些问题? </think> ### `GetReportData` 方法功能与逻辑解析 #### 1. **核心功能** 此方法用于**从 Oracle 数据库提取实验数据**,通过调用存储过程 `PKG_TEST_API.GET_DATA_FOR_EDI_NEW`,将输入参数转换为输出记录列表。主要实现数据查询格式转换。 #### 2. **输入/输出结构** ```csharp public List<OutputRecord> GetReportData(InputRecord record) ``` - **输入**:`InputRecord` 对象,包含: - `TEST_END_DATE_FROM/TO`:测试完成时间范围 - `CUSTOMER_NUMBER`:客户ID列表(整数数组) - `KEY_CLIENT`:客户名称 - **输出**:`List<OutputRecord>` 对象列表,每条记录包含实验报告数据字段 #### 3. **执行流程** ##### (1) 数据库连接初始化 ```csharp using (OracleConnection _conn = new OracleConnection(GetConnectionString())) using (OracleCommand _cmd = _conn.CreateCommand()) { _cmd.CommandType = CommandType.StoredProcedure; _cmd.CommandText = "PKG_TEST_API.GET_DATA_FOR_EDI_NEW"; _conn.Open(); ``` - 使用 `OracleConnection` 创建数据库连接 - 设置命令类型为**存储过程**,指定过程名 `PKG_TEST_API.GET_DATA_FOR_EDI_NEW` - 显式打开连接(ODP.NET 需要手动打开)[^1] ##### (2) 参数绑定 ```csharp _cmd.Parameters.Add("V_TEST_END_DATE_FROM", OracleDbType.Date).Value = record.TEST_END_DATE_FROM; _cmd.Parameters.Add("V_TEST_END_DATE_TO", OracleDbType.Date).Value = record.TEST_END_DATE_TO; // 数组参数特殊处理 if (record.CUSTOMER_NUMBER != null && record.CUSTOMER_NUMBER.Count > 0) { OracleParameter param = new OracleParameter("V_CUSTOMER_NUMBER", OracleDbType.Int32); param.Direction = ParameterDirection.Input; param.Value = record.CUSTOMER_NUMBER.ToArray(); param.UdtTypeName = "ARRAY_NUMBER"; // 自定义数组类型 _cmd.Parameters.Add(param); } else { _cmd.Parameters.Add("V_CUSTOMER_NUMBER", OracleDbType.Array).Value = DBNull.Value; } ``` - **日期参数**:直接绑定 `OracleDbType.Date` - **数组参数**: - 当客户ID列表非空时,转换为整数数组 - 指定 `UdtTypeName = "ARRAY_NUMBER"` 匹配 Oracle 自定义类型 - 空值时传递 `DBNull.Value`(避免存储过程异常) ##### (3) 数据获取与转换 ```csharp using (OracleDataReader dr = _cmd.ExecuteReader()) { DataTable dt = new DataTable(); dt.Load(dr); // 读取数据到DataTable return DataTableToList(dt); // 转换为对象列表 } ``` - 通过 `OracleDataReader` 流式读取数据 - 使用 `DataTable.Load()` 填充内存表 - 调用 `DataTableToList` 转换为强类型列表(通过反射实现) #### 4. **关键技术点** 1. **Oracle 数组处理**: - 使用 `OracleDbType.Array` + `UdtTypeName` 传递整型数组 - 需预先在 Oracle 创建类型: ```sql CREATE TYPE ARRAY_NUMBER AS VARRAY(100) OF NUMBER(10); ``` 2. **类型转换机制**: ```csharp private List<OutputRecord> DataTableToList(DataTable dt) { return dt.AsEnumerable().Select(row => { OutputRecord obj = new OutputRecord(); foreach (PropertyInfo prop in obj.GetType().GetProperties()) { if (dt.Columns.Contains(prop.Name)) prop.SetValue(obj, row[prop.Name] == DBNull.Value ? null : row[prop.Name]); } return obj; }).ToList(); } ``` - **反射映射**:自动匹配 DataTable 列名与对象属性名 - **空值处理**:将 `DBNull` 转换为 `null` #### 5. **执行效果示例** 假设输入: ```json { "TEST_END_DATE_FROM": "2023-01-01", "TEST_END_DATE_TO": "2023-01-31", "CUSTOMER_NUMBER": [101, 205], "KEY_CLIENT": "ABC_Corp" } ``` 存储过程执行流程: ```mermaid sequenceDiagram participant API participant Oracle API->>Oracle: 调用 PKG_TEST_API.GET_DATA_FOR_EDI_NEW Note right of Oracle: 参数:<br/>V_TEST_END_DATE_FROM=2023-01-01<br/>V_TEST_END_DATE_TO=2023-01-31<br/>V_CUSTOMER_NUMBER=[101,205]<br/>V_KEY_CLIENT='ABC_Corp' Oracle-->>API: 返回DataTable(多行数据) API->>API: 转换为List<OutputRecord> ``` ### 相关问题 1. 如何处理 Oracle 存储过程返回的游标数据? 2. 使用反射进行对象映射时有哪些性能隐患? 3. 在 C# 中如何优化大数据量的 DataTable 转换? 4. Oracle 数组类型(ARRAY_NUMBER)需要怎样的数据库配置? : Oracle ODP.NET 连接管理规范 [^2]: 数据库数组参数绑定技术 [^3]: 反射在数据映射中的应用场景
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值