【问题标题】:Problem with the return type of a stored procedure存储过程的返回类型问题
【发布时间】:2008-12-31 22:42:07
【问题描述】:

我有一个存储过程,它创建一个表,然后以某种方式从数据库表中填充该表,然后从该表中选择所有内容,然后删除该表。问题是,我如何使用该删除表中的选定列即时使用DataContext 我总是将存储过程的结果放在该存储过程类型的列表中

例如:

MyDataContext db=new MyDataContext();

public List<Base_RetriveItemResulte> RetriveItem(int ItemId)

{ 

    List<Base_RetriveItemResulte> ItemList=db.Base_RetriveItem(ItemId).ToList<Base_RetriveItemResulte>(); 

    return ItemList;

} 

//Base_RetriveItem 是数据上下文中的存储过程,删除表“GetSubcategories”的存储过程的问题是它不能被放入一个结果类型为 db.GetSubcategories(CategoryId) 我期望的列表中将 GetSubcategories(CategoryId) 的结果放入类型列表中

List<GetSubcategoriesResult> 

但是没有这样的类型!!如何从删除的表中获取选定的列?

【问题讨论】:

  • Sara,你应该看看这个网站上其他帖子的结构。它不是一个论坛,如果您尝试像一个论坛一样使用它,它会变得非常混乱。请编辑您的原始帖子或使用 cmets 回复那些试图提供帮助的人。

标签: linq-to-sql stored-procedures


【解决方案1】:

编辑: 请阅读问题末尾留下的 cmets。如果您不像其他人那样参与,那会让人感到困惑和沮丧,而那些愿意帮助您的人只会忽略您的请求。

请在您的帖子中提供一些信息。如果我们没有明确的信息,我们就是在疯狂猜测并做出假设。

  • 您使用什么语言?
  • 您使用的是 MSSQL、MySQL、Oracle 吗?什么版本?
  • Linq to SQL、Linq to EF 或其他 ORM 解决方案?

该存储过程看起来不像返回值单个结果,而是使用递归和游标“遍历”结果。非常非常非常脏。

SP 才是真正的问题所在。我知道您可能无法修复它,但您可能会更好:a) 制作自己的存储过程,或 b) 使用 dataAdapter 或其等效项以老式的方式调用存储过程。

另外一点,您最好看看我给您的代码示例,并了解它不太容易出现错误和其他问题。我们的方法有几个关键区别,您应该花时间去理解。

原帖: 存储过程通常返回数据集,而不是数组列表(那些是 .NET 类型)。您的实现也可以使用一些清理。

改成这样,语法错误见谅,我整天都在做VB。

注意:ID 两个字母都大写,还要观察变量在每个作用域中是如何声明的。您可能想要选择不同的模式,但这是标准的示例。

//retrieves a list of strings related to the itemID
public List<String> RetriveItem(int itemID)
{

  // declare our return value
  List _itemList = new List<String>; // int, whatever type of list

  // create a data context with the using statement (so it will be cleaned up when
  // the operation is completed.
  using (MyDataContext _db=new MyDataContext()) 
  {

     // get the data from the stored procedure
     DataSet _ds = _db.Base_RetriveItem(itemID);

     // go through each row in the first table (you may have more tables to look in
     foreach DataRow _dr in _ds.Tables(0)
     {
        // adds the first column value in the row to the return list.
        _itemList.Add(Convert.ToString(_dr(0)); //convert to whatever type your list is.
     }
  }

return _itemList;

} 

您也可以在 using 块中使用 IQueryable。

 var listOfItems = from i in _db._db.Base_RetriveItem(itemID) select i;
 foreach i in listOfItems 
 {
   _itemList.Add(i); //convert to whatever type your list 
 }

如果没有更多细节和反馈,很难提供。

"是从数据存储过程 上下文存储的问题 删除表的过程 获取子类别”

这真是令人困惑。该过程是一个 GET,这意味着它获取数据,而不是 DROPS 一个表。请澄清这一点。

【讨论】:

  • DataSet 是 .Net 类型。 msdn.microsoft.com/en-us/library/system.data.dataset.aspx我理解你对这个问题的沟通不畅感到沮丧,但为什么要尝试回答你不明白的问题呢?
  • 呃。我知道数据集是一种 .NET 类型。如果您有一个选择行的存储过程,它们的格式是数据集还是 ORM 列表?在 OP 发布 SP 之前,只有一个 GET 过程的描述。
【解决方案2】:

我不知道这是否是您需要的确切解决方案,但我过去必须做的一件事是通过使用非常直接的 SQL 语句设置事物的代码端来“愚弄”LinqToSQL (使存储过程只做一个非常简单的选择,它为您提供所需的确切数据结构[例如从临时视图中选择])。然后,一旦您完成了所有代码的连接,您就可以对存储过程进行更改以添加其高级功能。只要您不重新生成相关的 LinqToSQL 内容,它就应该继续工作。

【讨论】:

    【解决方案3】:

    这是一个有用的MSDN article

    根据本文,您应该期望您的结果为 GetSubcategoriesResult 的 IEnumerable。然而,你得到的是一个 int!

    无法将类型 'int' 隐式转换为 ...

    你需要找到这个方法的生成源:db.GetSubcategories(RootCat);并检查返回类型。您需要去找设计器并对其进行处理,直到它为您提供正确的 IEnumerable 结果,而不是行数(int)。


    如果设计者不配合,可以退回到手动执行方式:

    步骤 1. 创建类来保存返回类型:

    public class MyCustomResult
    {
      public int CategoryId{get;set;}
      public int ParentCategoryId{get;set;}
      public int IsActive{get;set;}
    }
    

    步骤 2. 使用 ExecuteQuery 调用存储过程:

    public List<MyCustomResult> GetResult(int RootCat)
    {
      List<MyCustomResult> result =
        db.ExecuteQuery<MyCustomResult>("EXEC _BASE_GetSubcategories {0}", RootCat);
      return result;
    }
    

    ExecuteQuery 将获取(单个)结果集并通过与属性名称匹配的列名将其映射到类 (MyCustomResult)。

    有些人可能对这种手动解决方案感到失望,但 LinqToSql 对存储过程(以及具有存储过程的复杂映射场景)的支持相当薄弱,有时必须被覆盖。


    就存储过程而言,它似乎是一个标准的“任意深度树遍历”。在 SQL 中实现这一点并没有真正好的方法,因此我认为存储过程的实现很好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多