Проблема с типом возврата хранимой процедуры - PullRequest
2 голосов
/ 01 января 2009

У меня есть хранимая процедура, которая создает таблицу, затем как-то заполняет эту таблицу из таблиц базы данных, затем выбирает все из этой таблицы, затем удаляет эту таблицу. Проблема в том, как я могу использовать выбранные столбцы из этой удаленной таблицы, которую я использую 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 ]

1 голос
/ 01 января 2009

EDIT: Пожалуйста, прочитайте комментарии, оставленные в конце вашего вопроса. Если вы не будете участвовать, как все остальные, это смущает и расстраивает, а те, кто охотно вам поможет, просто проигнорируют ваш запрос.

Пожалуйста, предоставьте некоторую информацию в вашем посте. Если у нас нет четкой информации, мы дико угадываем и делаем предположения.

  • Какой язык вы используете?
  • Используете ли вы MSSQL, MySQL, Oracle? Какая версия?
  • Linq для SQL, Linq для EF или другое решение ORM?

Эта хранимая процедура не выглядит так, как будто ВОЗВРАЩАЕТ единичный результат значения, а использует рекурсию и курсоры для "обхода" результата. Очень, Очень, Очень грязно.

Эта SP - реальная проблема здесь. Я понимаю, что вы, возможно, не сможете исправить это, но вам может быть лучше: а) сделать свою собственную хранимую процедуру или б) назвать хранимую процедуру старым добрым способом с помощью dataAdapter или его эквивалента.

В качестве другого пункта, вам было бы целесообразно взглянуть на пример кода, который я вам дал, и понять, что он будет менее подвержен ошибкам и другим проблемам. В наших подходах есть несколько ключевых отличий, которые вы должны уделить время, чтобы понять.

Оригинальный пост: Хранимые процедуры обычно возвращают DataSets, а не 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;

} 

В качестве альтернативы вы можете использовать IQueryable внутри блока using.

 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 означает, что она ПОЛУЧАЕТ данные, а не УДАЛЯЕТ ТАБЛИЦУ. Пожалуйста, уточните это.

0 голосов
/ 02 января 2009

Вот полезная статья MSDN .

Согласно этой статье, вы должны ожидать, что ваши результаты будут IEnumerable из GetSubcategoriesResult. Однако вместо этого вы получаете int!

Невозможно неявно преобразовать тип 'int' в ...

Вам необходимо найти сгенерированный источник для этого метода: db.GetSubcategories (RootCat); и проверить тип возврата. Вам нужно обратиться к конструктору и пнуть его, пока он не даст вам правильный IEnumerable результат вместо числа строк (целое число).


Если дизайнер не сотрудничает, вы можете вернуться к ручному методу выполнения:

Шаг 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, и поэтому реализация хранимой процедуры в порядке.

0 голосов
/ 01 января 2009

Я не знаю, является ли это именно тем решением, которое вам нужно, но одна вещь, которую мне приходилось делать в прошлом, это «дурачить» LinqToSQL, настраивая сторону кода с помощью очень простого оператора SQL (сделайте хранимую процедуру не более чем очень простым выбором, который дает вам точную структуру данных, которая вам нужна [например, выбор из временного представления]). Затем, когда у вас есть весь код, вы можете внести изменения в хранимую процедуру, чтобы добавить ее расширенные функциональные возможности. До тех пор, пока вы не восстановите связанный материал LinqToSQL, он должен продолжать работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...