2015-12-17 31 views
0

是否有已建立的方法/工具根據Oracle數據庫表的列自動創建包含變量的生成C#類/結構?使用ODP.NET,從Oracle數據庫的列信息創建C#類/結構表

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

目前,我正在手動創建每個類。但我意識到隨着桌子的數量變得更多,我的方式變得更乏味。

任何人都遇到同樣的問題,有一個很好的工具來緩解任務?

回答

1

微軟推出了Code Generation and T4 Text Templates,它可以用來使用一些控制邏輯來生成文本輸出。 This article描述瞭如何從DB自動生成代碼。 T4是Visual Studio的一部分,因此不需要安裝其他軟件。爲了完成你需要編寫T4文本模板是

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

您還可以修改this article中描述的方法,其中顯示瞭如何從Datatable對象創建類。基本上你可以使用System.CodeDom命名空間來創建一個包含你需要的屬性的類。爲了解決該問題,您需要完成以下步驟:

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

我認爲第一種方法(使用T4)更有效且易於理解。例如,讓我們假設你對所有類都有相同的方法。你可以簡單地將這個方法添加到T4文件中,這很清楚這個方法在做什麼。第二種方法需要更多的代碼來定義方法。

UDPATE

NHibernate Mapping Generator允許產生從DB中的域代碼。您可以簡單地複製這些生成的類(從Domain Code選項卡)並更改它們。

如果您只是需要爲您的類生成屬性,那麼您可以修改爲適應Oracle描述的SQL腳本here

+0

謝謝,我會通讀你的文章鏈接。 – Ian

0

Entity Framework與ODP.NET一起工作,爲您做這些事情,還有更多...是否有一個特定的原因,您沒有使用任何可用的ER映射器?

+0

對不起,[實體框架版本6](https://entityframework.codeplex.com)與ODP.NET – Digifaktur

3

從一般意義上說,您正在討論如何將數據庫的模式/元數據轉換爲不同的表單。大多數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 Developer Snip

在過去,我已經添加列生成一切從的OracleCommand參數,輸入用於網絡。然後,您可以採用某種模板機制來生成整個類,包括數據訪問方法等.T4是一個選項,但我使用了CodeSmith的Generator產品。

雖然像Entities或NHibernate這樣的對象關係映射器也做了很多這樣的工作,但我不明白他們的另一個目的,那就是將數據從數據庫到中間層的實際移動抽象出來 - 查詢語言對我來說,使用過於虛弱/複雜。我更喜歡堅持使用sql本身,也許像微型模擬器一樣 - 當然,我使用上述相同的技術來爲CRUD操作生成sql。

相關問題