🔍【深入解析】解決 Oracle EF Core 報錯「ORA-00904: 'FALSE': 無效的 ID」的終極指南


1. 錯誤現象與訊息解讀

你在用 .NET EF Core 撰寫資料存取層(Repository)時,執行 Oracle 查詢時突然爆出:

Oracle.ManagedDataAccess.Client.OracleException (0x80004005): ORA-00904: "FALSE": 無效的 ID

這段英文翻譯是「FALSE:無效的識別字(ID)」,也就是 Oracle 資料庫根本不認得 "FALSE" 這個東西。






2. 報錯主因:EF Core 與 Oracle 的布林陷阱

EF Core 在 SQL Server 或 MySQL 下支援 TRUE/FALSE 常數,但Oracle 完全不支援布林常數
只要你在 LINQ to Entities 查詢裡「產生布林運算」——例如:

select new DTO { IsValid = (someCondition) }

EF Core 會把這段程式碼自動轉換成 SQL:

CASE WHEN ... THEN True ELSE False END

Oracle 完全不認得 TrueFalse 這兩個關鍵字,導致 ORA-00904 直接報錯!






3. 常見誤區:C# 條件運算與三元運算

你以為 assign 給 string 型別就安全?
其實只要你在 select new {...} 內寫條件判斷(? :)、ToString()、或 DateTime.MinValue 判斷,
EF Core 都會自動轉成 Oracle 看不懂的 SQL。

錯誤寫法:

ORI_PLAN_DATE = (z.ORI_PLAN_DATE == null || z.ORI_PLAN_DATE == DateTime.MinValue)
    ? null
    : z.ORI_PLAN_DATE.Value.ToString("yyyy-MM-dd")

這會導致 Oracle 端產生

CASE WHEN (...) THEN True ELSE False END

報錯收場!






4. 實戰案例 — 專案程式碼片段分析

典型 select new 錯誤範例

var query = from z in _context.Table
            select new DTO
            {
                // 這裡一用條件式就爆炸
                IsNull = (z.SOME_DATE == null)
            };

錯誤訊息

ORA-00904: "FALSE": 無效的 ID


5. 如何正確解法?三步驟徹底根治

Step 1. 不要在 LINQ 查詢(IQueryable)用條件運算與 C# 特有語法。
Step 2. 只 select 出原始欄位,資料抓進記憶體(ToList/AsEnumerable)後再做運算。
Step 3. DTO 型別完全不要用 bool,只用 int 或 string。

修正後最佳寫法

// 1. 先查出 List
var dataList = await _context.Table.Where(...).ToListAsync();

// 2. 再用 C# 處理運算與格式
var result = dataList.Select(z => new DTO
{
    IsNull = (z.SOME_DATE == null) ? 1 : 0,
    ORI_PLAN_DATE = (z.ORI_PLAN_DATE == null || z.ORI_PLAN_DATE == DateTime.MinValue)
        ? ""
        : z.ORI_PLAN_DATE.Value.ToString("yyyy-MM-dd")
}).ToList();



6. 最佳實踐與預防建議

  • 所有布林條件判斷,轉成 1/0 或 "Y"/"N" 字串存 DTO

  • 資料庫查詢端只做簡單 select,不要做三元運算、ToString()、日期格式轉換等 C# 行為

  • Model/DTO 層不用 bool 型別,完全用 int/string 替代







7. 常見Q&A

Q1:為什麼 SQL Server 沒這問題,Oracle 卻會報錯?

A1:SQL Server/MySQL 支援 TRUE/FALSE 常數,Oracle 僅支援 1/0'Y'/'N'
EF Core 產生 SQL 時沒幫你自動轉換,就會報錯。

Q2:除了條件運算,還有什麼會讓 Oracle 報 ORA-00904?

A2:任何 Oracle 不認得的識別字(如欄位拼錯、用保留字、還有 select new 產生 bool 結果)都會報這個錯。






8. 結語

只要你遇到 EF Core + Oracle 報 "ORA-00904: 'FALSE': 無效的 ID"
第一步檢查 select new {...} 有沒有用到條件運算或 assign bool,全部改成 int/string,並把複雜運算移到記憶體運作階段,保證一勞永逸!

留言

這個網誌中的熱門文章

🛠【ASP.NET Core + Oracle】解決 ORA-00904 "FALSE": 無效的 ID 錯誤與資料欄位動態插入顯示問題

🛠【實戰排除教學】從 VS Code 的 _logger 錯誤,到 PowerShell 找不到 npm/serve,再到 Oracle ORA-03135 連線中斷——一次搞懂!

🔎如何在 Oracle PL/SQL 儲存過程中為文字欄位加入換行符號(CHR(10))——以 Updlcmremark 為例