LINQToSQL可以与使用sp_executeSQL的sproc一起使用吗?如果没有,你怎么处理?

Joh*_*ohn 3 stored-procedures linq-to-sql

LINQToSQL不喜欢我的sproc.它说sproc的返回类型为"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

返回

这个sproc返回一组FooID | FooName元组.

  • 12345 | 探戈舞
  • 98765 | 现金

目标

此存储过程将用于在搜索页面上返回搜索结果.这是一种相当常见的搜索模式.我想找到符合条件的Foos,但条件正在应用于单独的表格.我可以选择直接编写此查询而不使用sp_executeSQL,但是这种方法的作用是创建只包含实际查询表的SQL.在现实世界的场景中,我可以有12个连接,而不是1个,这种方法允许我只将实际用作条件的连接串起来.

问题

LINQ to SQL不喜欢它.它表示此查询返回类型"none",并且不允许我指定返回类型.我不确定其他ORM,如NHibernate,Entity Framework或LLBLGen是否能够处理这个问题.LINQToSQL到目前为止在该项目上运行良好,我95%完成了该项目,并且不想为单个方法使用不同的ORM.如果我进行进一步的更改,它可能是重构的东西,但是现在,我还没准备好为此转换到不同的ORM.

我真的想找到一种方法在LinqToSql中使这个工作!我不确定它是否可以.我没有找到关于这个明显限制的任何官方文件.

到目前为止我正在考虑的替代方案

到目前为止,我已经提出了一些替代方案.我不喜欢他们中的任何一个,所以我真的希望有人有一个很好的"黑客"来解决这个问题.这些是我到目前为止所得到的:

  • 重写sproc.摆脱sp_executeSQL.对所有表进行LEFT JOIN.
  • 使用ADO.Net并手动滚动该方法.
  • 不要使用sproc,而是尝试在LINQ中进行所有过滤.

Jef*_*ard 5

您可以使用Linq2SQL来调用您的sproc,但实体建模器可能无法为您生成调用包装器,因为它无法确定sproc返回的内容,因此您必须自己创建调用包装器.

为此,创建一个实体模型"非设计者"模块,其中部分类定义与您的实体模型数据上下文(和实体,如果需要)匹配,并像这样定义调用包装器.

namespace bar.Context
{
    public partial class EntityModelDataContext
    {
        /// <summary>
        /// LINQ to SQL class mapper for Foo StoredProcedure
        /// </summary>
        /// <remarks>
        /// This one is too tough for the LINQ to SQL modeler tool to auto-generate
        /// </remarks>
        /// <returns></returns>
        [Function(Name = "dbo.Foo")]
        [ResultType(typeof(bar.Entity.tbFoo))]
        public ISingleresult<bar.Entity.tbFoo> Foo([Parameter(Name = "BarName", DbType = "varchar")] string barname)
        {
            IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), barname);
            return ((ISingleResult<bar.Entity.tbFoo>)(result.ReturnValue));
        }
    }
}

namespace bar.Entity
{
    /// <summary>
    /// Data Modeler couldn't figure out how to generate this from the sproc
    /// hopefully your entity model generated this and you don't need to replicate it
    /// </summary>
    [Table(Name = "dbo.tbFoo")]
    public partial class tbFoo        {
       ....
    }
}
Run Code Online (Sandbox Code Playgroud)