.net – SqlMetal错误地生成我的存储过程的返回类型(LINQ)
|
嗨有一个存储过程总是返回一行取决于一个参数: IF @bleh = 1 SELECT TOP 1 Xyz FROM Abc ELSE SELECT TOP 1 Def FROM Abc 我必须使用SqlMetal生成DataContext,但此存储过程返回IMultipleResults,这是一个错误.相反它应该返回一个ISingleResult … 如果我删除if(放置一个SELECT调用),则会生成一个ISingleResult返回类型. 有任何想法吗? 解决方法您描述的场景是设计的.我已经使用.NET 3.5和.NET 4.0 Beta 2进行了测试,并得到了相同的结果.给定一个使用IF / ELSE结构的SPROC,生成的结果和使用的工具是:> SqlMetal:IMultipleResults 这是微软的supported by Matt Warren:
在this blog post Dinesh Kulkarni评论了相反的情况,设计师没有添加IMultipleResults并使用ISingleResult.他说(重点补充):
此外,Scott Gu’s post和this MSDN article中标题为“处理来自SPROC的多个结果形状”的部分都显示IMultipleResults与使用相同结构的SPROC一起使用. 好的,现在怎么样?有一些解决方法,有些比其他更好. 重写SPROC 您可以重写SPROC,以便SqlMetal使用ISingleResult生成函数.这可以通过以下方式实现 重写#1 – 将结果存储在变量中: DECLARE @Result INT
IF @Input = 1
SET @Result = (SELECT TOP 1 OrderId FROM OrderDetails)
ELSE
SET @Result = (SELECT TOP 1 ProductId FROM OrderDetails ORDER BY ProductId DESC)
SELECT @Result As Result
显然,类型需要相似或者可以投射到另一个类型.例如,如果一个是INT而另一个是DECIMAL(8,2),则使用小数来保持精度. 重写#2 – 使用案例陈述: 这与Mark’s suggestion相同. SELECT TOP 1 CASE WHEN @Input = 1 THEN OrderId ELSE ProductId END FROM OrderDetails 使用UDF而不是SPROC 您可以使用scalar-valued UDF并调整查询以使用UDF格式(与上面提到的变量方法相同). SqlMetal将为它生成一个ISingleResult,因为只返回一个值. CREATE FUNCTION [dbo].[fnODIds]
(
@Input INT
)
RETURNS INT
AS
BEGIN
DECLARE @Result INT
IF @Input = 1
SET @Result = (SELECT TOP 1 UnitPrice FROM OrderDetails)
ELSE
SET @Result = (SELECT TOP 1 Quantity FROM OrderDetails ORDER BY Quantity DESC)
RETURN @Result
END
伪造SPROC&把它关掉 这可行,但比以前的选项更乏味.此外,将来使用SqlMetal会覆盖这些更改并要求重复该过程.使用部分类并移动相关代码将有助于防止这种情况. 1)更改您的SPROC以返回单个SELECT语句(注释掉您的实际代码),例如SELECT TOP 1 OrderId FROM OrderDetails 2)使用SqlMetal.它将生成一个ISingleResult: [Function(Name = "dbo.FakeODIds")]
public ISingleResult<FakeODIdsResult> FakeODIds([Parameter(Name = "Input",DbType = "Int")] System.Nullable<int> input)
{
IExecuteResult result = this.ExecuteMethodCall(this,((MethodInfo)(MethodInfo.GetCurrentMethod())),input);
return ((ISingleResult<FakeODIdsResult>)(result.ReturnValue));
}
3)将您的SPROC更改回其原始格式,但对返回的结果使用相同的别名.例如,我将OrderId和ProductId作为FakeId返回. IF @Input = 1
SELECT TOP 1 OrderId As FakeId FROM OrderDetails
ELSE
SELECT TOP 1 Quantity As FakeId FROM OrderDetails ORDER BY Quantity DESC
注意我这里没有使用变量,而是直接使用您最初使用的格式. 4)由于我们使用的是FakeId别名,我们需要调整生成的代码.如果导航到在步骤2中为您生成的映射类(在我的情况下为FakeODIdsResult).该类将使用代码中步骤1的原始列名,在我的情况下使用OrderId.事实上,如果步骤1中的陈述是别名的,即,可以避免整个步骤,即. SELECT TOP 1 OrderId作为FakeId来自OrderDetails.如果你没有,你需要进去调整一下. FakeODIdsResult将使用OrderId,它将返回任何内容,因为它别名为FakeId.它看起来与此类似: public partial class FakeODIdsResult
{
private System.Nullable<int> _OrderId;
public FakeODIdsResult()
{
}
[Column(Storage = "_OrderId",DbType = "Int")]
public System.Nullable<int> OrderId
{
get
{
return this._OrderId;
}
set
{
if ((this._OrderId != value))
{
this._OrderId = value;
}
}
}
}
您需要做的是将OrderId重命名为FakeId,将_OrderId重命名为_FakeId.完成后,您可以像往常一样使用上面的ISingleResult,例如: int fakeId = dc.FakeODIds(i).Single().FakeId; 这就结束了我已经使用过并且能够在主题上找到的内容. (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- sql-server-2008 – SQL Server无法预测的选择结果(dbms错误
- SQL Server:超过5列的动态枢轴
- SQL datetime需要读取00:00:00.000
- join – Spark 2.0.0错误:PartitioningCollection要求其所
- sql – 如何有效地选择所有重复项
- MySQL8.0.11版本的新增特性介绍
- sql-server – 如何在sql server 2008上安装全文?
- sql – 如果另一个表中不存在id,则从表中删除
- SQL Server 判断触发器正在处理的是插入,删除还是更新触发
- sql-server – 我们如何从DBA保护我们的数据?
