簡體   English   中英

使用ODP.NET,從Oracle DB表的列信息創建C#類/結構

[英]With ODP.NET, Create C# class/struct from Column Info of an Oracle DB's Table

是否存在一種確定的方法/工具來自動創建根據Oracle數據庫表的列包含變量的C#類/結構?

我目前正在使用ODP.Net來處理Oracle DB中的許多表。 為了方便我處理數據庫表,我為讀取的每個表創建了一個唯一的C#類,該類存儲了給定數據庫行的信息

目前,我正在手動制作每個班級。 但是我意識到隨着表數量的增加,我的方法變得越來越乏味。

是否有人遇到相同的問題,並且擁有減輕工作負擔的好工具?

一般而言,您是在談論將數據庫的架構/元數據轉換為其他形式。 大多數RDBMS將此數據公開為表。 例如,這是我用來獲取所有列數據,清理它(如刪除下划線)並將其轉換為.net類型和語句的查詢:

with metadata as
(
        select 
          utc.table_name, 
          utc.column_name, 
          replace(initcap(replace( lower(utc.column_name) ,'_',' ')),' ','') as column_name_clean,
          initcap(replace( lower(utc.column_name) ,'_',' ')) as column_name_space,
          rtrim(substr(utc.column_name,1,26),'_') as column_name_26,
         case utc.data_type
            when 'DATE' then 'DateTime'
            when 'VARCHAR2' then 'String'
            when 'CLOB' then 'String'
            when 'NUMBER' then 
              case when utc.data_scale=0 then 
                case 
                  when utc.data_precision = 19 then 'Int64'
                  when utc.data_precision = 9 then 'Int32'
                  when utc.data_precision = 4 then 'Int16'
                  when utc.data_precision = 1 then 'Boolean'
                  else 'Int'|| utc.data_precision  end
              else 'Decimal' end
            when 'CHAR' then 
              case when utc.data_length = 1 then 'Char'
              else 'String' end
            else '' end as clr_data_type,
         case utc.data_type
            when 'DATE' then 'DateTime'
            when 'VARCHAR2' then 'Text'
            when 'CLOB' then 'MultilineText'
            when 'CHAR' then 'Text'
            else '' end as mvc_data_type, 
         case utc.data_type
            when 'DATE' then 'Date'
            when 'TIMESTAMP' then 'TimeStamp'
            when 'VARCHAR2' then 'Varchar2'
            when 'CLOB' then 'Clob'
            when 'NUMBER' then 
              case when utc.data_scale=0 then 
                case 
                  when utc.data_precision = 19 then 'Int64'
                  when utc.data_precision = 9 then 'Int32'
                  when utc.data_precision = 4 then 'Int16'
                  when utc.data_precision = 1 then 'Decimal-Boolean'
                  else 'Int'|| utc.data_precision  end
                else 'Decimal' end

            when 'CHAR' then 'Char'
            else '' end as odp_data_type, 
          utc.Data_Type as native_data_type,
         case when utc.data_type = 'VARCHAR2' or utc.data_type='CHAR' then Data_Length
            else null end as mvc_data_range, 
          utc.data_length,
          utc.data_precision,
          utc.data_scale,
          utc.nullable,
            case 
              when utc.data_scale > 0 then 
                '^\d{' || (nvl(utc.data_precision,1)-nvl(utc.data_scale,0)) || '}(\.\d{' || nvl(utc.data_scale,0) || '})?$'
              else '' end as validation_reg_ex,
          'n.' || trim(rpad(' ', nvl(utc.data_scale,0), 'd')) as validation_format,
          case utc.data_type
            when 'NUMBER' then
              case when utc.data_scale=0 then utc.data_precision
              else utc.data_precision + 1 end -- +1 for the decimal
            else
              utc.data_length end as max_string_length,
          case ac.constraint_type when 'P' then 'Y' else 'N' end as PRIMARY_KEY,
          ac.constraint_type
        from user_tab_columns utc
        left join all_cons_columns acc
          join all_constraints ac on ac.constraint_name = acc.constraint_name and ac.owner = acc.owner and ac.constraint_type='P'
          on utc.column_name=acc.column_name and utc.table_name=acc.table_name
        where utc.table_name not like 'BIN%'
        order by utc.table_name, utc.column_id
)
select 'public ' || clr_data_type || ' ' || column_name_clean || ' {get; set;}' as ClassProperty, m.*
from metadata m;

您會注意到第一列,將其中的一些字段連接在一起以形成類屬性:

SQL開發人員片段

過去,我添加了一些列來生成從OracleCommand參數到網絡輸入的所有內容。 然后,您可以使用某種模板機制進一步擴展該類以生成整個類,包括數據訪問方法等。T4是一個選項,但我使用了CodeSmith的Generator產品。

盡管像Entities或NHibernate這樣的對象關系映射器也做了很多此類工作,但我不欣賞它們的另一個目的,即抽象數據從數據庫到中間層的實際移動,它們使用的查詢語言也是如此對我無能為力。 我更喜歡使用sql本身,也許更喜歡使用像dapper這樣的微型orm-當然,我也使用上述相同的技術來生成用於CRUD操作的sql :)。

Microsoft引入了代碼生成和T4文本模板 ,可使用某些控制邏輯來生成文本輸出。 本文介紹了一種如何自動從數據庫生成代碼的方法。 T4是Visual Studio的一部分,因此無需安裝其他軟件。 要完成此任務,您需要編寫T4文本模板

文本塊和可以生成文本文件的控制邏輯的混合物。 在Visual C#或Visual Basic中,控制邏輯被編寫為程序代碼的片段。

您還可以采用本文介紹的方法, 方法說明了如何從Datatable對象創建類。 基本上,您可以使用System.CodeDom命名空間來創建一個包含所需屬性的類。 為了解決該問題,您需要完成以下步驟:

  1. 使用CodeTypeDeclaration類聲明一個類。
  2. 為每一列創建屬性( CodeMemberField )創建一個屬性並將其添加到類中。
  3. 創建一個名稱空間( CodeNamespace )並將類添加到其中。
  4. 使用CSharpCodeProvider類生成一個.cs文件。

我認為第一種方法(使用T4)更加有效和易於理解。 例如,假設您對所有類都具有相同的方法。 您可以簡單地將此方法添加到T4文件中,很明顯該方法在做什么。 第二種方法需要更多代碼來定義該方法。

UDPATE

NHibernate Mapping Generator允許從數據庫生成域代碼。 您可以簡單地復制這些生成的類(從“ Domain Code選項卡中)並進行更改。

如果你只需要為您的類的屬性,那么你可以適應適應甲骨文所描述的SQL腳本在這里

實體框架可與ODP.NET協同工作,並且對您有幫助,甚至更多。...是否有特定原因導致您不使用任何可用的ER映射器?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM