LINQToSQL不喜欢我的sproc。它说sproc的返回类型为“none”,这可能是因为我使用sp_ExecuteSQL语句来生成结果。
我有一个类似于以下的存储过程
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元组。
此存储过程将用于在搜索页面上返回搜索结果。这是一种相当常见的搜索模式。我想找到符合条件的Foos,但条件正在应用于单独的表格。我可以选择直接编写此查询而不使用sp_executeSQL,但是这种方法的作用是创建只包含实际查询表的SQL。在现实世界的场景中,我可以有12个连接,而不是1个,这个方法允许我只将实际用作标准的连接串起来。
LINQ to SQL不喜欢它。它表示此查询返回类型“none”,并且不允许我指定返回类型。我不确定其他ORM,如NHibernate,Entity Framework或LLBLGen是否能够处理这个问题。 LINQToSQL到目前为止在该项目上工作得很好,我95%完成了该项目,并且不想为单个方法使用不同的ORM。如果我进行进一步的更改,它可能会重构,但就目前而言,我还没准备好为此转换到不同的ORM。
我真的想找到一种方法让这个工作在LinqToSql中!我不确定它是否可以。我没有找到关于这个明显限制的任何官方文件。
到目前为止,我已经提出了一些替代方案。我不喜欢他们中的任何一个,所以我真的希望有人有一个很好的“黑客”来解决这个问题。这些是我到目前为止所得到的:
答案 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
匹配条件,你可以做任何你想做的事。
如果searchString
为null
,那么您只需使用dbContextObject.Foos.All()