2

我的項目有兩個EF 4.1上下文,一個是模型優先,另一個是代碼優先。這兩種情況都擴展了DbContext並連接到Oracle數據庫。EntityFramework 4.1代碼優先Oracle插入PL/SQL代碼

當執行一個更新一個大表(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

答案是雙重的。

從所生成的SQL卸下PL/SQL

在數據庫中的列名稱是所有大寫字母(「UWI」),而在類中的屬性是駱駝情況下(「UWI」) 。我改變了屬性名稱全部大寫和EF刪除PL/SQL代碼,併產生僅僅是SQL:

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

然而,這並不能提高性能。

爲什麼更新很慢

與DBA合作,跟蹤查詢後,我們發現,EF是在西印度羣島的值綁定到一個十六進制字符串,而不是「2224434.」這導致Oracle進行全表掃描並影響性能。我需要在Uwi屬性指定列的類型,就像這樣:

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

HasColumnType是靈丹妙藥,我的更新語句在80毫秒返回。