[英]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;
您會注意到第一列,將其中的一些字段連接在一起以形成類屬性:
過去,我添加了一些列來生成從OracleCommand參數到網絡輸入的所有內容。 然后,您可以使用某種模板機制進一步擴展該類以生成整個類,包括數據訪問方法等。T4是一個選項,但我使用了CodeSmith的Generator產品。
盡管像Entities或NHibernate這樣的對象關系映射器也做了很多此類工作,但我不欣賞它們的另一個目的,即抽象數據從數據庫到中間層的實際移動,它們使用的查詢語言也是如此對我無能為力。 我更喜歡使用sql本身,也許更喜歡使用像dapper這樣的微型orm-當然,我也使用上述相同的技術來生成用於CRUD操作的sql :)。
Microsoft引入了代碼生成和T4文本模板 ,可使用某些控制邏輯來生成文本輸出。 本文介紹了一種如何自動從數據庫生成代碼的方法。 T4是Visual Studio的一部分,因此無需安裝其他軟件。 要完成此任務,您需要編寫T4文本模板
文本塊和可以生成文本文件的控制邏輯的混合物。 在Visual C#或Visual Basic中,控制邏輯被編寫為程序代碼的片段。
您還可以采用本文介紹的方法, 該方法說明了如何從Datatable
對象創建類。 基本上,您可以使用System.CodeDom
命名空間來創建一個包含所需屬性的類。 為了解決該問題,您需要完成以下步驟:
CodeTypeDeclaration
類聲明一個類。 CodeMemberField
)創建一個屬性並將其添加到類中。 CodeNamespace
)並將類添加到其中。 CSharpCodeProvider
類生成一個.cs
文件。 我認為第一種方法(使用T4)更加有效和易於理解。 例如,假設您對所有類都具有相同的方法。 您可以簡單地將此方法添加到T4文件中,很明顯該方法在做什么。 第二種方法需要更多代碼來定義該方法。
UDPATE
NHibernate Mapping Generator允許從數據庫生成域代碼。 您可以簡單地復制這些生成的類(從“ Domain Code
選項卡中)並進行更改。
如果你只需要為您的類的屬性,那么你可以適應適應甲骨文所描述的SQL腳本在這里 。
實體框架可與ODP.NET協同工作,並且對您有幫助,甚至更多。...是否有特定原因導致您不使用任何可用的ER映射器?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.