【问题标题】:Question about linq2sql关于 linq2sql 的问题
【发布时间】:2011-08-03 20:57:40
【问题描述】:

我有一些带有 linq2sql 类的遗留代码。 DataContext 类对存储过程的定义如下:

 [Function(Name="dbo.sp_Goods_SelectBySection")]
        public ISingleResult<sp_Goods_SelectBySectionResult> sp_Goods_SelectBySection([Parameter(Name="SectionId", DbType="Int")] System.Nullable<int> sectionId)
        {
            IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), sectionId);
            return ((ISingleResult<sp_Goods_SelectBySectionResult>)(result.ReturnValue));
        }

但是当我尝试在我自己的项目中创建相同的程序时,设计师会创建具有不同实现的程序:

[Function(Name="dbo.sp_Goods_SelectBySection")]
        public int sp_Goods_SelectBySection([Parameter(Name="SectionId", DbType="Int")] System.Nullable<int> sectionId)
        {
            IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), sectionId);
            return ((int)(result.ReturnValue));
        }

而且我无法更改方法属性中的类型。

这是存储过程的代码。

ALTER PROCEDURE [dbo].[sp_Goods_SelectBySection]
(
    @SectionId INT
)
AS
BEGIN

    SET NOCOUNT ON;

    SELECT 
        Goods.Id,
        Goods.[Name],
        TypeId,
        Makerid,
        Price,
        [Description],
        Term,
        Types.Name AS TypeName,
        Makers.Name AS MakerName,
        GoodsImage.SmallImageUrl AS MainImageUrl,
        Goods.IsDeleted,
        Goods.Rang
    FROM Goods 
         INNER JOIN Types ON (Types.Id = Goods.TypeId)
         INNER JOIN Makers ON (Makers.Id = Goods.MakerId)
         LEFT JOIN GoodsImage ON ( GoodsImage.GoodId = Goods.Id AND GoodsImage.IsMain = 1 AND GoodsImage.IsDeleted = 0 )
    WHERE 
        Types.SectionId = @SectionId
        AND Goods.IsDeleted  = 0
    ORDER BY Rang ASC       
END

为什么?以及如何创建返回 ISingleResult 而不是 int 的过程?

请注意,我有很多这样的程序,我认为手动修改每个程序都不是好主意。


我猜是设计师的问题。因为我创建了新的测试项目,它工作正常。感谢所有帮助过我的人。尤其是安德拉斯·佐尔坦。

【问题讨论】:

  • 你确定这是在你指向设计者的数据库中编译的过程的实际文本吗?
  • @JohnOpincar 是的,这是程序的实际文本。我在这两种情况下都使用相同的程序。
  • @JohnOpincar - 我支持你。 C#/Sql 块中的 SP 名称不匹配...
  • @Neir0 - 现在您已经更新了代码,以便所有名称都匹配;您能否尝试简单地从 L2S 设计器中删除 SP,然后从服务器资源管理器中再次将其拖回?
  • @Andras Zoltan 我刚刚复制了其他程序来提问。对不起。我编辑了问题。

标签: c# tsql linq-to-sql


【解决方案1】:

抱歉,稍微误解了你的问题,但我会保留我最初的 cmets

请记住,存储过程返回一个结果集,而不是一个值;除非您计算 return 语句中返回的值。因此,您需要一个类型来环绕返回的列和行。

如果您知道 SP 返回映射到您的一种表类型的行集,则可以将返回类型更改为表。但是你不能只返回'an int'。

请参阅此链接:http://social.msdn.microsoft.com/forums/en-US/linqprojectgeneral/thread/1667a989-08a0-402c-9358-e4637406a75f(对不起,它在 MSDN 论坛上结束了 - 不是这样:$)以及来自该 http://msdn.microsoft.com/en-us/library/bb386975.aspx 的链接主题

更新

L2S 使用等效的 SQL 反射来计算 SP 返回的内容,以便自动生成结果。

如果 SP 没有 SELECT,或者它只有一个 RETURN,您将获得映射函数的基本 int 返回类型。如果 SP 使用IF 语句来分叉并相应地返回不同的结果,这种事情可能会合法或错误地发生; L2S 不可能找出可以满足所有可能结果的单一返回类型,因此它只满足其中一个。

正如@JohnOpincar 在他的 cmets 中提到的那样,您在此处发布的 SP 是否实际上是您映射的那个存在一个问号 - 因为名称不一样?我的猜测是你拖错了 SP - 里面只有一个 RETURN,或者它返回了多个东西并且 L2S 已经失败了。

更新 2

好的,您已经更改了源代码中的名称。我的建议是从 L2S 设计器中删除 SP(以及您可能对此 SP 进行的任何其他手动尝试),然后从服务器资源管理器中再次将其拖回,确保它与您从中拖动它的服务器/数据库相同。使用您发布的 SQL,L2S 肯定能够弄清楚结果集是什么,因为它非常简单。

【讨论】:

  • 好的。但是我如何在设计师中做到这一点?我不想将返回值从 ISingleResult 更改为 int。我想从 int 更改为 ISingleResult。
  • @Neir0 好的 - Linq to Sql 检查有关 SP 的元数据以生成正确的返回类型。如果它看到 SP 主体不是 SELECT 而只是 RETURNS,它将返回一个 int。在这种情况下,我会回应@JohnOpincar 所说的:澄清肯定它所查看的 SP 具有您认为它具有的主体(因为您发布的 sp 与那个不具有相同的名称你在 C# 中映射!)
  • @Andras Zoltan 这是我的错误。我复制了其他程序来提问。但在我的项目中是可以的。我正在使用遗留项目中的部分代码。无处不在的遗留代码使用带有 ISingleResult 的过程,但我的过程返回 INT。如您所见,IF 语句没有问题。
  • @Andras Zoltan 按照您的建议,我从设计器中删除了存储过程,然后再次添加。我也有同样的问题。过程返回 int。我可以做些什么来检测问题的根源?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-29
  • 2011-09-05
  • 2010-12-29
  • 1970-01-01
  • 2013-11-20
  • 2010-09-26
  • 2021-11-29
相关资源
最近更新 更多