2

我的项目有两个 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?

4

1 回答 1

1

答案有两个。

从生成的 SQL 中删除 PL/SQL

数据库中的列名全大写(“UWI”),而类的属性是驼峰式(“Uwi”)。我将属性名称更改为全大写,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 毫秒内返回。

于 2013-04-09T15:09:46.067 回答