使用ef6创建oracle数据库的实体模型遇到的问题及解决方案
解决方案中的数据层项目最初使用的是oracle 11g + ef5 创建的实体模型,在分页时遇到了skip参数为0报错的问题,没有找到相关资料。
于是决定升级到ef6,在oracle官网中得知,oracle data provider for .net in odac 12c release 3 开始支持ef6(https://docs.oracle.com/cd/e56485_01/win.121/e55744/release_changes.htm#cihgiaeg)
安装步骤:
1.安装odac,下载地址
2.数据层项目的.net版本改成4.5以上,使用nuget安装 entityframework 6 +oracle.manageddataaccess +oracle.manageddataaccess.entityframework,都安装最新稳定版。
安装后app.config和web.config都会被加入如下配置项
<configsections> <!-- for more information on entity framework configuration, visit http://go.microsoft.com/fwlink/?linkid=237468 --> <section name="entityframework" type="system.data.entity.internal.configfile.entityframeworksection, entityframework, version=6.0.0.0, culture=neutral, publickeytoken=b77a5c561934e089" requirepermission="false" /> <section name="oracle.manageddataaccess.client" type="oracleinternal.common.odpmsectionhandler, oracle.manageddataaccess, version=4.122.1.0, culture=neutral, publickeytoken=89b483f429c47342" /> </configsections> <entityframework> <defaultconnectionfactory type="system.data.entity.infrastructure.localdbconnectionfactory, entityframework"> <parameters> <parameter value="mssqllocaldb" /> </parameters> </defaultconnectionfactory> <providers> <provider invariantname="system.data.sqlclient" type="system.data.entity.sqlserver.sqlproviderservices, entityframework.sqlserver" /> <provider invariantname="oracle.manageddataaccess.client" type="oracle.manageddataaccess.entityframework.eforacleproviderservices, oracle.manageddataaccess.entityframework, version=6.122.1.0, culture=neutral, publickeytoken=89b483f429c47342" /> </providers> </entityframework> <system.data> <dbproviderfactories> <remove invariant="oracle.manageddataaccess.client" /> <add name="odp.net, managed driver" invariant="oracle.manageddataaccess.client" description="oracle data provider for .net, managed driver" type="oracle.manageddataaccess.client.oracleclientfactory, oracle.manageddataaccess, version=4.122.1.0, culture=neutral, publickeytoken=89b483f429c47342" /> </dbproviderfactories> </system.data> <runtime> <assemblybinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentassembly> <publisherpolicy apply="no" /> <assemblyidentity name="oracle.manageddataaccess" publickeytoken="89b483f429c47342" culture="neutral" /> </dependentassembly> </assemblybinding> </runtime> <oracle.manageddataaccess.client> <version number="*"> <datasources> <datasource alias="sampledatasource" descriptor="(description=(address=(protocol=tcp)(host=localhost)(port=1521))(connect_data=(service_name=orcl))) " /> </datasources> </version> </oracle.manageddataaccess.client>
注意 entityframework和 system.data中的版本号,nuget安装后自动生成的一般没问题,我在安装之前把网上找的资料里的配置项放在里面了,但是版本号不一致,程序启动不了,一直没注意到版本号,
找了好一会才发现是这两个地方。
3.然后就可以添加实体模型了。此时如果vs中显示找不到与ef6 兼容的实体框架提供程序,需要将配置文件中的ef节的 <provider invariantname="system.data.sqlclient" type="system.data.entity.sqlserver.sqlproviderservices, entityframework.sqlserver" />
删掉或者注释掉,保存后再重新尝试添加实体模型。
添加实体模型时需要先不选择数据库里的表,即生成空模型,然后打开edmx文件,在模型浏览器中选中实体模型,在属性中把ddl生成模板改成ssdltooracle.tt (vs),数据库生成工作流改成generate oracle via t4 (tpt).xaml (vs)。
这么做的原因是如果ddl生成模板使用默认项ssdltooracle.tt ,oracle中的number(1,0)和number(2,0)类型的字段生成的实体属性的类型会是int16,然后运行的时候报映射不匹配的错误(错误代码2019)。
报错原因是oracle从odp.net 12.1.0.2开始为ef6采用新的默认类型映射,官网说明https://docs.oracle.com/cd/e56485_01/win.121/e55744/entitydatatypemapping.htm#odpnt8303,其中的 new default mappings 段。
ssdltooracle.tt模板生成的属性的类型是number(1,0)对应boolean,number(2,0)对应byte,这个对应关系与新映射是一致的。
附上ef5的映射
oracle type | default edm type | custom edm type |
---|---|---|
number(1,0) |
int16 |
bool |
number(2,0) to number(3,0)
|
int16 |
byte |
number(4,0) |
int16 |
int16 |
number(5,0) |
int16 |
int32 |
number(6,0) to number(9,0)
|
int32 |
int32 |
number(10,0) |
int32 |
int64 |
number(11,0) to number(18,0)
|
int64 |
int64 |
number(19,0) |
int64 |
decimal |
总结
以上所述是小编给大家介绍的使用ef6创建oracle数据库的实体模型遇到的问题及解决方案,希望对大家有所帮助
上一篇: 别看车不咋滴,费油啊!