【发布时间】:2009-07-08 15:55:01
【问题描述】:
LINQToSQL 不喜欢我的存储过程。它说存储过程的返回类型为“none”,这可能是因为我正在使用 sp_ExecuteSQL 语句来生成结果。
SQL Server Sproc 代码
我有一个类似于下面的存储过程
CREATE PROCEDURE Foo
@BarName varchar(50)
AS
BEGIN
DECLARE @SQL NVARCHAR(1024)
SET @SQL = 'SELECT tbFoo.FooID, tbFoo.Name FROM tbFOO ';
IF @BarName IS NOT NULL
BEGIN;
SET @SQL = @SQL
+ ' JOIN tbBar '
+ ' ON tbFoo.FooID = tbBar.FooID '
+ ' AND tbBar.BarName = ''' + @BarName + ''''
END;
EXEC sp_executeSQL @SQL
END
返回
这个存储过程返回一组 FooID | FooName 元组。
- 12345 |探戈
- 98765 |现金
目标
此存储过程将用于在搜索页面上返回搜索结果。这是一种相当常见的搜索模式。我想找到满足条件的 Foos,但是该条件正在应用于单独的表。我本可以选择不使用 sp_executeSQL 直接编写此查询,但是这种方法的作用是创建仅包含实际查询的表的 SQL。在现实世界的场景中,我可以有 12 个连接,而不是 1 个,这种方法只允许我将实际用作标准的连接串在一起。
问题
LINQ to SQL 不喜欢它。它说这个查询返回类型“none”并且不允许我指定返回类型。我不确定其他 ORM,例如 NHibernate、Entity Framework 或 LLBLGen 是否能够处理这个问题。到目前为止,LINQToSQL 在该项目上运行良好,我已经完成了 95% 的项目,并且不想为单个方法使用不同的 ORM。如果我进行进一步的更改,可能需要重构,但目前,我还没有准备好为此切换到不同的 ORM。
我真的很想找到一种方法在 LinqToSql 中完成这项工作!我不确定它是否可以。我还没有找到任何关于这个明显限制的官方文档。
目前我正在考虑的替代方案
到目前为止,我已经提出了一些替代方案。我不喜欢其中任何一个,所以我真的希望有人有一个很好的“hack”来解决这个问题。这些是我到目前为止所得到的:
- 重写存储过程。摆脱 sp_executeSQL。对所有表执行 LEFT JOIN。
- 使用 ADO.Net 手卷方法。
- 不要使用存储过程,而是尝试在 LINQ 中进行所有过滤。
【问题讨论】:
标签: linq-to-sql stored-procedures