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

时间:2009-07-08 15:55:02

标签: linq-to-sql stored-procedures

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中进行所有过滤。

2 个答案:

答案 0 :(得分: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        {
       ....
    }
}

答案 1 :(得分:0)

是否有某些原因无法使用Linq中的对象属性处理查询?

我需要查看表模式,包括外键链接,以便给出一个很好的示例,但它类似于:

dbContextObject.Foos.Where(foo=> foo.Bars.Where(bar=> bar.BarName == searchString))

然后你会IEnumerable Foo匹配条件,你可以做任何你想做的事。

如果searchStringnull,那么您只需使用dbContextObject.Foos.All()