存储过程的返回类型的问题

时间:2008-12-31 22:42:07

标签: linq-to-sql stored-procedures

我有一个存储过程,创建一个表,然后以某种方式从数据库的表中填充此表,然后选择此表中的所有内容然后删除此表。问题是,我如何使用所删除的表中的选定列我使用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> 

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

3 个答案:

答案 0 :(得分:1)

修改 请阅读问题末尾留下的评论。如果你不像其他人一样参与,那会让人感到困惑和沮丧,那些愿意帮助你的人会忽略你的请求。

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

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

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

这个SP是真正的问题。我知道你可能无法修复它,但你可能会更好:a)制作你自己的存储过程,或b)使用dataAdapter或其等价物以旧的方式调用存储过程。

另外一点,你应该明智地看一下我给你的代码示例,并明白它会更容易出错和其他问题。我们的方法有几个关键的区别,你应该花时间去理解。

原帖: 存储过程通常返回DataSet,而不是arraylist(这些是.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 
 }

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

  

“是来自数据的存储过程   上下文存储的问题   放下桌子的程序   GetSubcategories“

这真令人困惑。该过程是GET,这意味着它是GETS数据,而不是DROPS一个TABLE。请澄清一下。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

这是一个有用的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中没有一种真正好的方法可以实现这一点,因此在我看来存储过程的实现很好。