EntityFramework 4.1 Code First Oracle插入PL / SQL代码

时间:2013-04-04 14:20:58

标签: oracle11g ef-code-first entity-framework-4.1 ef-model-first

我的项目有两个EF 4.1上下文,一个是模型优先,另一个是代码优先。这两个上下文都扩展了DbContext并连接到Oracle数据库。

当执行对大表(5M记录)的更新时,模型优先上下文会产生预期的SQL,并且它会快速运行(毫秒):

update <schema.table_name> set field = 'value' where id = 1234

当执行对大表(4.7M记录)的更新时,代码优先上下文会产生一些奇怪的PL / SQL:

declare
"UWI" nvarchar2(
                128)
;
begin
update
                "SCHEMA"."TABLE"
set "FIELD" = 'VALUE' /* :p0 */,

where ("UWI" = '2224434' /* :p37 */)

returning
"UWI" into
"UWI";
open '' /* :p38 */ for select

"UWI" as "UWI" 
from dual;
end;

此更新语句需要3秒钟才能完成。

以下是代码优先上下文的代码优先的EntityTypeConfiguration:

public WellEntityConfiguration()
{
    this.ToTable("TABLE", "SCHEMA");

    this.HasKey(entity => entity.Uwi);
    this.Property(entity => entity.Uwi).HasColumnName("UWI");

    ... //lots of properties being set
}

我可以设置一个配置来强制EF生成简单的更新语句而不是疯狂的PL / SQL吗?

1 个答案:

答案 0 :(得分:1)

答案是双重的。

从生成的SQL中删除PL / SQL

数据库中的列名是all-caps(“UWI”),而类上的属性是camel-case(“Uwi”)。我将属性名称更改为all-caps,EF删除PL / SQL代码并仅生成SQL:

UPDATE "SCHEMA"."TABLE"
SET "FIELD" = "VALUE"
WHERE ("UWI" = '2224434')

但是,这并没有提高性能。

更新为何缓慢

在使用DBA跟踪查询后,我们发现EF将Uwi的值绑定到十六进制字符串而不是“2224434”。这导致Oracle进行全表扫描并影响性能。我需要在Uwi属性上指定列类型,如下所示:

this.Property(entity => entity.Uwi).HasColumnName("UWI").HasColumnType("VARCHAR2");

HasColumnType是神奇的子弹,我的更新语句在80毫秒内返回。