Linq to sql LINQToSQL能否与使用sp_executeSQL的存储过程一起使用?如果没有,你如何处理?

Linq to sql LINQToSQL能否与使用sp_executeSQL的存储过程一起使用?如果没有,你如何处理?,linq-to-sql,stored-procedures,Linq To Sql,Stored Procedures,LINQToSQL不喜欢我的存储过程。它说存储过程的返回类型为“none”,这可能是因为我正在使用sp_ExecuteSQL语句生成结果 SQL Server存储过程代码 我有一个类似于以下内容的存储过程 创建过程Foo @BarName varchar(50) AS 开始 声明@SQL NVARCHAR(1024) SET@SQL='从tbFoo中选择tbFoo.FooID、tbFoo.Name' 如果@BarName不为空 开始 设置@SQL=@SQL +“加入tbBar” +“ON tb

LINQToSQL不喜欢我的存储过程。它说存储过程的返回类型为“none”,这可能是因为我正在使用sp_ExecuteSQL语句生成结果

SQL Server存储过程代码 我有一个类似于以下内容的存储过程

创建过程Foo
@BarName varchar(50)
AS
开始
声明@SQL NVARCHAR(1024)
SET@SQL='从tbFoo中选择tbFoo.FooID、tbFoo.Name'
如果@BarName不为空
开始
设置@SQL=@SQL
+“加入tbBar”
+“ON tbFoo.FooID=tbBar.FooID”
+'和tbBar.BarName=''+@BarName+'''''>
结束
EXEC sp_executeSQL@SQL
结束

退换商品 此存储过程返回一组FooID | FooName元组

  • 12345探戈
  • 98765 |现金
目标 此存储过程将用于在搜索页面上返回搜索结果。这是一种相当常见的搜索模式。我想找到满足条件的foo,但是该条件将应用于一个单独的表。我可以选择不使用sp_executeSQL直接编写这个查询,但是这种方法所做的是创建只包含实际被查询的表的SQL。在一个真实的场景中,我可以有12个连接,而不是1个,这种方法允许我只将实际用作标准的连接串在一起

问题 LinqtoSQL不喜欢它。它表示此查询返回类型“none”,不允许我指定返回类型。我不确定其他的ORMs,比如NHibernate、entityframework或LLBLGen是否能够处理这个问题。到目前为止,LINQToSQL在这个项目上工作得很好,我已经完成了95%的项目,不想为一个方法使用不同的ORM。如果我做进一步的修改,这可能是需要重构的,但是现在,我还没有准备好仅仅为了这个而切换到一个不同的ORM

我真的很想找到一种在LinqToSql中工作的方法!我不确定它能不能。我还没有找到任何关于这一明显限制的官方文件

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

  • 重新编写存储过程。摆脱sp_executeSQL。对所有表执行左联接
  • 使用ADO.Net和手动滚动的方法
  • 不要使用存储过程,而是尝试在LINQ中执行所有过滤

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

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

      dbContextObject.Foos.Where(foo=> foo.Bars.Where(bar=> bar.BarName == searchString))
      
      然后,您将有一个符合条件的
      IEnumerable
      of
      Foo
      s,您可以用它做任何您想做的事情


      如果
      searchString
      null
      ,则只需使用
      dbContextObject.Foos.All()

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

      为此,创建一个实体模型“非设计器”模块,该模块的部分类定义与实体模型数据上下文(以及必要的实体)相匹配,并定义如下所示的调用包装器

      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        {
             ....
          }
      }
      
      namespace bar.Context
      {
      公共分部类EntityModelDataContext
      {
      /// 
      ///Foo StoredProcess的LINQ到SQL类映射器
      /// 
      /// 
      ///对于LINQ to SQL modeler工具来说,这一点太难了,无法自动生成
      /// 
      /// 
      [函数(Name=“dbo.Foo”)]
      [结果类型(typeof(bar.Entity.tbFoo))]
      公共ISingleresult Foo([Parameter(Name=“BarName”,DbType=“varchar”)]字符串BarName)
      {
      IExecuteResult=this.ExecuteMethodCall(this,((MethodInfo)(MethodInfo.GetCurrentMethod()),barname);
      返回((IsingResult)(result.ReturnValue));
      }
      }
      }
      名称空间bar.Entity
      {
      /// 
      ///Data Modeler无法确定如何从存储过程生成此数据
      ///希望您的实体模型生成了这个,您不需要复制它
      /// 
      [表(Name=“dbo.tbFoo”)]
      公共部分类tbFoo{
      ....
      }
      }
      
      在您的示例中,如果searchString为NULL,LINQ将做什么?dbContextObject.Foos.Where(foo=>foo.bar.Where(bar=>bar.BarName==searchString))实际工作吗?我遇到一个错误,无法将类型“System.Collections.Generic.IEnumerable”隐式转换为“bool”,谢谢。这就是我要找的。现在我有了一个处理查询和UDF的通用解决方案,这些查询和UDF返回的结果中LINQ不够聪明,无法推断数据类型,但我可以手动编写代码。