Linq查詢鏈接guid與varchar字段

使用場景

在數據庫設計中進場會出現一些通用表,如通用附件表,通常都是經過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

把函數添加到db模型

能夠直接編輯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.");
}

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模型的,可是應該能夠經過其餘方式添加,我沒試,我隨便說的,你別信啊。數據庫設計

參考文檔:
如何:調用自定義數據庫函數ide

相關文章
相關標籤/搜索