在數據庫設計中進場會出現一些通用表,如通用附件表,通常都是經過ForeignTable(關聯的表名)和ForeignKey(關聯表的主鍵)與其餘表關聯。這樣的表在數據庫中沒有外鍵關係,並且通常ForeignKey的類型是varchar,爲了兼容其餘表的主鍵可能不同。這樣在Linq查詢的時候就不能直接關聯了,以下代碼會編譯不經過:git
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類型,編譯經過了運行也會報錯,以下:github
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的。sql
若是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
能夠直接編輯edmx模型文件添加以下代碼:編程
<Function Name="ConvertGuidToChar" ReturnType="varchar" Schema="dbo" > <Parameter Name="id" Mode="In" Type="uniqueidentifier" /> </Function>
也可經過從數據庫更新模型添加
c#
/// <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."); }
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模型的,可是應該能夠經過其餘方式添加,我沒試,我隨便說的,你別信啊。數據庫設計
參考文檔:
如何:調用自定義數據庫函數ide