Linq查詢連接guid與varchar字段
- 2019 年 10 月 10 日
- 筆記
使用場景
在數據庫設計中進場會出現一些通用表,如通用附件表,一般都是通過ForeignTable(關聯的表名)和ForeignKey(關聯表的主鍵)與其他表關聯。這樣的表在數據庫中沒有外鍵關係,而且一般ForeignKey的類型是varchar,為了兼容其他表的主鍵可能不一樣。這樣在Linq查詢的時候就不能直接關聯了,如下代碼會編譯不通過:
from a in db.WorkflowInstance join b in d.xxx//xxx.ID為guid類型 on new { a.ForeignTable, a.ForeignKey } equals new { ForeignTable = nameof(xxx), ForeignKey = b.ID } select a;
因為xxx.id是Guid(uniqueidentifier)類型和WorkflowInstance.ForeignKey是string(varchar)類型。就算是強行把xxx.id轉成string類型,編譯通過了運行也會報錯,如下:
from a in db.WorkflowInstance join b in d.xxx//xxx.ID為guid類型 on new { a.ForeignTable, a.ForeignKey } equals new { ForeignTable = nameof(xxx), ForeignKey = b.ID+"" } select a;
以為這段代碼最終都會轉成sql語句,而Guid是不能直接轉換成varchar的。
解決方案
如果xxx.id是數字類型(int,float,double,decimal)是可以使用SqlFunctions.StringConvert(xxx.id)轉換成string類型,這樣就可以了,SqlFunctions.StringConvert支持double和decimal,基本上數字都可以轉換成這兩種類型,但是注意下轉換時小數點後0的個數,因為string比較時少一個0是不一樣的。 但是Guid不行,因為沒有對應的函數。通過面向百度編程,微軟爸爸給我們提供了一個解決方案:自定義函數。相當於我們自己實現一個SqlFunctions.StringConvert()。
首先在數據庫定義一個轉換函數
if EXISTS(select * from dbo.sysobjects where id = object_id(N'[dbo].[ConvertGuidToChar]') and xtype in (N'FN', N'IF', N'TF')) drop function [dbo].ConvertGuidToChar GO CREATE FUNCTION ConvertGuidToChar ( @id UNIQUEIDENTIFIER ) RETURNS VARCHAR(50) AS BEGIN RETURN CONVERT(VARCHAR(50),@id) END
把函數添加到db模型
可以直接編輯edmx模型文件添加如下代碼:
<Function Name="ConvertGuidToChar" ReturnType="varchar" Schema="dbo" > <Parameter Name="id" Mode="In" Type="uniqueidentifier" /> </Function>
也可通過從數據庫更新模型添加

添加自定義函數對應的方法
/// <summary> /// sql函數Guid轉varchar /// </summary> /// <param name="id"></param> /// <returns></returns> [EdmFunction("iLISModel.Store", "ConvertGuidToChar")] public static string ConvertGuidToChar(Guid id) { throw new NotSupportedException("Direct calls are not supported."); }
Linq中使用自定義函數轉換類型
from a in d.WorkflowInstance join b in d.xxx//xxx.ID為guid類型 on new { a.ForeignTable, a.ForeignKey } equals new { ForeignTable = nameof(xxx), ForeignKey = SqlFunctionsExtension.ConvertGuidToChar(b.ID) } select a;
這樣就能正常查詢數據了。 註:codefirst是沒有edmx模型的,但是應該可以通過其他方式添加,我沒試,我隨便說的,你別信啊。