在数据库设计中进场会出现一些通用表,如通用附件表,通常都是经过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