我已设置测试数据库和控制台应用以确认以下内容:
给定具有以下功能的SQL数据库:
CREATE FUNCTION ufn_GTFO
(
@Guid as uniqueidentifier
)
RETURNS VARCHAR(100)
AS
BEGIN
-- Declare the return variable here
DECLARE @Result as VARCHAR(100)
-- Add the T-SQL statements to compute the return value here
SELECT @Result = 'This is a test'
-- Return the result of the function
RETURN @Result
END
GO
以下表格:
CREATE TABLE [dbo].[Test](
[PKey] [int] IDENTITY(1,1) NOT NULL,
[WFT] [uniqueidentifier] NULL,
CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED
(
[PKey] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
标量值函数ufn_GTFO通常是可组合的,例如以下C#:
static void ConcreteTest()
{
DataClasses1DataContext db = new DataClasses1DataContext();
var q = from t in db.Tests
select new { t.PKey, GTFO = db.ufn_GTFO(t.WFT) };
var p = q.ToArray();
}
被翻译成以下SQL:
SELECT [t0].[PKey], [dbo].[ufn_GTFO]([t0].[WFT]) AS [GTFO] FROM [dbo].[Test] AS [t0]
但是,如果我使用重构 - >在DataContext上提取接口,并使用它的实例:
static void InterfaceTest()
{
IDataClasses1DataContext db = new DataClasses1DataContext();
var q = from t in db.Tests
select new { t.PKey, GTFO = db.ufn_GTFO(t.WFT) };
var p = q.ToArray();
}
我得到以下SQL,并且每个记录都会调用ufn_GTFO一次.ToArray()会枚举结果。
SELECT [t0].[PKey], [t0].[WFT] AS [guid]
FROM [dbo].[Test] AS [t0]
所以,我的问题是为什么会发生这种情况,如何在仍然使用界面的情况下阻止它?
更新1:我已经比较了具体方法生成的IL和接口方法,它们的区别仅在于对接口的引用和编译器生成的显示类没有&# 39;似乎与结果有关。
答案 0 :(得分:1)
linq to sql在很大程度上依赖于将类(datacontext)成员映射到数据库成员的属性。您的接口可能没有ufn_GRFO方法的FunctionAttribute。如果没有该属性,C#世界和SQL函数之间的链接就会被切断;然而。您的接口也没有使用DatabaseAttribute进行修饰,因为该属性仅对类而不是接口有效。没有该属性,您已经切断了C#和整个数据库之间的链接。默认情况下,Linq使用AttributeMappingSource映射DataContext中的类型成员。感觉接口是有问题的类型,并且该类型已切断到该数据库的链接,由于您无法将数据库属性应用于该数据库,您的默认映射源将不会将函数ufn_GRFO映射到数据库函数,相反,linq会将其视为.NET函数,以便使用WFT字段中的数据进行调用。
我怀疑解决此问题的方法是为您的datacontext提供自定义MappingSource实现,并忽略DatabaseAttribute并仅考虑属性上的属性。
http://msdn.microsoft.com/en-us/library/system.data.linq.mapping.functionattribute.aspx
http://msdn.microsoft.com/en-us/library/system.data.linq.mapping.databaseattribute.aspx
http://msdn.microsoft.com/en-us/library/system.data.linq.mapping.attributemappingsource.aspx
http://msdn.microsoft.com/en-us/library/system.data.linq.mapping.mappingsource.aspx