Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Тип используемый в using, должен быть явно конвертируем 
:(
    Опции темы
ДобренькийПапаша
Дата 13.8.2009, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 14.1.2006
Где: г.Москва

Репутация: нет
Всего: 7



В названии темы ошибка, тут говорится о неявном преобразовании)))    Такая ошибка:
'object': type used in a using statement must be implicitly convertible to 'System.IDisposable'

Код

object tmpObj = null;
using(tmpObj=ProcInvoke.ExecuteQuery("GetCourses", QueryType.ExecuteScalar,                //Не нравится такое выражение в using
                                                                        CommandType.StoredProcedure,
                                                                        new ProcParams("@FacShortName",
                                                                                       SqlDbType.VarChar, 50,
                                                                                       curNode.Text,
                                                                                       ParameterDirection.Input)))
{
}

//Однако вот так, всё нормально:
using (SqlDataReader myReaderForPass =
                 (SqlDataReader)
                 ProcInvoke.ExecuteQuery("AuthSecur", QueryType.ExecuteReader, CommandType.StoredProcedure,
                                         new ProcParams("@Login", SqlDbType.VarChar, 50, username,
                                                        ParameterDirection.Input)))
{
}

//Вызываемая функция (дело правда не в ней я так понимаю)
public static object ExecuteQuery(string procName, QueryType queryType, 
            CommandType cmdType, params ProcParams[] ex)
        {
           SqlConnection curConnect = ProcInvoke.GetDBConnection(ProcInvoke.ServerPath,
                                                                  ProcInvoke.DataBasePath);
           try
           {
                curConnect.Open();

                SqlCommand curCommand = new SqlCommand(procName, curConnect);
                curCommand.CommandType = cmdType;

                if (ex != null)
                {
                    curCommand.Parameters.AddRange(ProcInvoke.GetParameter(ex));
                }
                
                switch (queryType)
                {
                    case QueryType.ExecuteReader:
                        {
                            SqlDataReader curReader = curCommand.ExecuteReader();
                            return curReader;
                        }
                    case QueryType.ExecuteNonQuery:
                        {
                            curCommand.ExecuteNonQuery();
                            curConnect.Close();
                            return null;
                        }
                    case QueryType.ExecuteScalar:
                        {
                      
                            object tmpObj = curCommand.ExecuteScalar();
                            return tmpObj;
                        }
              
                }
          
            }



Это сообщение отредактировал(а) ДобренькийПапаша - 13.8.2009, 13:35


--------------------
Меня зовут Себастьян Парейра, торговец чёрным деревом.
PM MAIL   Вверх
azesmcar
Дата 13.8.2009, 13:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 6
Всего: 211



Цитата(ДобренькийПапаша @  13.8.2009,  13:33 Найти цитируемый пост)
В названии темы ошибка, тут говорится о неявном преобразовании)))    Такая ошибка:
'object': type used in a using statement must be implicitly convertible to 'System.IDisposable'

А вопрос в чем? Object - не может быть сконвертирован в IDisposible, он не реализует этот интерфейс, SqlDataReader - реализует.

Добавлено через 3 минуты и 47 секунд
Из стандарта C#
Цитата

8.13 The using statement
The using statement obtains one or more resources, executes a statement, and then disposes of the resource.
using-statement:
using   (    resource-acquisition   )    embedded-statement
resource-acquisition:
local-variable-declaration
expression
A resource is a class or struct that implements System.IDisposable, which includes a single parameterless method named Dispose. Code that is using a resource can call Dispose to indicate that the resource is no longer needed. If Dispose is not called, then automatic disposal eventually occurs as a consequence of garbage collection.



Это сообщение отредактировал(а) azesmcar - 13.8.2009, 13:38
PM   Вверх
ДобренькийПапаша
Дата 13.8.2009, 13:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 14.1.2006
Где: г.Москва

Репутация: нет
Всего: 7



Это я уже понял)))
А решение какое?


--------------------
Меня зовут Себастьян Парейра, торговец чёрным деревом.
PM MAIL   Вверх
azesmcar
Дата 13.8.2009, 13:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 6
Всего: 211



Цитата(ДобренькийПапаша @  13.8.2009,  13:55 Найти цитируемый пост)
А решение какое? 

Не использовать using  smile или писать второй вариант.

Это сообщение отредактировал(а) azesmcar - 13.8.2009, 13:58
PM   Вверх
ДобренькийПапаша
Дата 13.8.2009, 14:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 14.1.2006
Где: г.Москва

Репутация: нет
Всего: 7



Если не использовать using то открытое соединение не закроется(((
 
Код

 public static object ExecuteQuery(string procName, QueryType queryType, 
            CommandType cmdType, params ProcParams[] ex)
        {
           SqlConnection curConnect = ProcInvoke.GetDBConnection(ProcInvoke.ServerPath,
                                                                  ProcInvoke.DataBasePath);
           try
           {
                curConnect.Open();

                SqlCommand curCommand = new SqlCommand(procName, curConnect);
                curCommand.CommandType = cmdType;

                if (ex != null)
                {
                    curCommand.Parameters.AddRange(ProcInvoke.GetParameter(ex));
                }
                #region switch QueryType
                switch (queryType)
                {
                    case QueryType.ExecuteReader:
                        {
                            SqlDataReader curReader = curCommand.ExecuteReader();
                            return curReader;
                        }
                    case QueryType.ExecuteNonQuery:
                        {
                            curCommand.ExecuteNonQuery();
                            curConnect.Close();
                            return null;
                        }
                    case QueryType.ExecuteScalar:
                        {
                            foreach(ProcParams cur in ex)
                            {
                                if (cur.Direction == ParameterDirection.Output)
                                {
                                    curCommand.ExecuteScalar();
                                    return curCommand;
                                }
                            }
                            object tmpObj = curCommand.ExecuteScalar();
                            return tmpObj;
                        }
                    default:
                        {
                            MessageBox.Show("Неизвестный тип запроса", "Ошибка запроса",
                                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                            curConnect.Close();
                            return null;
                        }
                }
                #endregion
            }
            catch(SqlException curEx)
            {
                MessageBox.Show(curEx.Message, curEx.Source);
                return null;
            }
        
        }
        
    }



--------------------
Меня зовут Себастьян Парейра, торговец чёрным деревом.
PM MAIL   Вверх
azesmcar
Дата 13.8.2009, 14:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 6
Всего: 211



Не нравиться мне эта функция..Вызывающий должен точно знать, что возвращает функция, то она значение возвращает, то SqlDataReader.
Но если функция должна возвращать object - тогда сделай приведение типа (впрочем как уже сделано) smile
Да, и SqlDataReader можно и самому закрыть, через функцию Close.

Это сообщение отредактировал(а) azesmcar - 13.8.2009, 14:05
PM   Вверх
mihryak
Дата 13.8.2009, 16:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 731
Регистрация: 28.4.2007
Где: С-Пб

Репутация: 19
Всего: 36



функция и правда дурацкая
никаких преимуществ перед прямыми вызовами ExetuteReader, ExecuteScalar, ExecuteNonQuery она не имеет - всё равно в каждом случае надо будет вызывать её с нужным QueryType, что мало отличается от прямого вызова нужного метода, да и потом нужно этот искусственный энум учитывать, чтобы знать, как с возвращённым значением работать
я бы объединил бы подготовительные действия с функцию, возвращающую DbCommand, а у неё уже вызывать один из трёх методов напрямую пользователем твоей обёртки, если команда будет наружу выдаваться, либо через обёрточные методы

попытки обобщить необобщаемое ни к чему хорошему не приводят, если бы с этими методами команды можно было бы работать одним и тем же образом, то, не сомневаюсь, в .Нет была бы заложена такая возможность
PM MAIL ICQ   Вверх
ДобренькийПапаша
Дата 13.8.2009, 17:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 14.1.2006
Где: г.Москва

Репутация: нет
Всего: 7



У меня дикий дубляж кода шёл, этой функцией я 1000 строк сократил, я сделал как надо, в моём случае работает очень хорошо... 
В каких-то других ситуациях, думаю это неоправдано. Хотя я думаю, что эту функцию можно-таки улучшить...

Цитата

я бы объединил бы подготовительные действия с функцию, возвращающую DbCommand, а у неё уже вызывать один из трёх методов напрямую пользователем твоей обёртки, если команда будет наружу выдаваться, либо через обёрточные методы


Хотя вот этот вариант, мне определённо нравится. Он логичен и прост. Возможно, так и сделаю. Просто сразу, честно говоря, не всегда видно как сделать просто и хорошо.

Это сообщение отредактировал(а) ДобренькийПапаша - 13.8.2009, 17:30


--------------------
Меня зовут Себастьян Парейра, торговец чёрным деревом.
PM MAIL   Вверх
ДобренькийПапаша
Дата 14.8.2009, 07:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 14.1.2006
Где: г.Москва

Репутация: нет
Всего: 7



Цитата

я бы объединил бы подготовительные действия с функцию, возвращающую DbCommand, а у неё уже вызывать один из трёх методов напрямую пользователем твоей обёртки, если команда будет наружу выдаваться, либо через обёрточные методы


Уважаемый Михряк, я раньше делал вот так:

Код

using (SqlConnection curConnect =
            ProcInvoke.GetDBConnection(ProcInvoke.ServerPath, ProcInvoke.DataBasePath))
            {
                try
                {
                      curConnect.Open();
                       var cmdForCathedrals = new SqlCommand("GetCathedralsOnFacs", curConnect);
                            cmdForCathedrals.CommandType = CommandType.StoredProcedure;

                            cmdForCathedrals.Parameters.Add(ProcInvoke.GetParameter("@FacFullName", SqlDbType.VarChar,   
                                                                                  50, cur.Text, ParameterDirection.Input));
                          SqlDataReader myReaderForFaculties = cmdForCathedrals.ExecuteReader();
                  }
                  catch (SqlException ex)
                  {
                        MessageBox.Show(ex.Message, ex.Source);
                  }
              }
               curConnect.Close();
//Класс ProcInvoke, функция GetDbConnection:
public static SqlConnection GetDBConnection(string source, string initCat)
        {
            var cnStr = new SqlConnectionStringBuilder();
            cnStr.IntegratedSecurity = true;
            cnStr.DataSource = source;
            cnStr.InitialCatalog = initCat;

            var cn = new SqlConnection();
            cn.ConnectionString = cnStr.ConnectionString;
            return cn;
        }
//Класс ProcInvoke, функция GetParameter:          //Ну вот здесь можно сделать, чтобы массив сразу передавать:
public static SqlParameter GetParameter(string parameterName, SqlDbType dbType,
                                                int size, Object value, ParameterDirection direction)
        {
            var curParam = new SqlParameter();
            curParam.ParameterName = parameterName;
            curParam.SqlDbType = dbType;
            if (size != 0)
            {
                curParam.Size = size;
            }
            if (value != null)
            {
                curParam.Value = value;
            }
            curParam.Direction = direction;
            return curParam;
        }               


И всё время дубляж нехилый получается, меня это загребло... using, try, openConnect, Command, Parameters, Execute, Read, CloseRead, catch, closeConnect ...  У меня программа напичкана вызовами мелких хранимых процедур....

Поэтому я и написал ту некрасивую функцию...
В моём конкретном случае единственный недостаток в ней , это то, что при передаче SqlDataReader коннект открытый висит (они в пуле размножаются насколько я знаю) (при других Execute я коннект спокойно закрываю...) Можно там массив объектов возвращать, то есть всё вытащить из DataReader... но это накладно...

Ну вобщем не знаю, что скажете? 

Это сообщение отредактировал(а) ДобренькийПапаша - 14.8.2009, 07:15


--------------------
Меня зовут Себастьян Парейра, торговец чёрным деревом.
PM MAIL   Вверх
mihryak
Дата 15.8.2009, 22:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 731
Регистрация: 28.4.2007
Где: С-Пб

Репутация: 19
Всего: 36



посмотри на такой вариант
Код

    public class DbManager : IDisposable
    {
        private DbConnection connection;

        public int ExecuteNonQuery(string procedureName, DbParameter[] parameters)
        {
            return CreateCommand(Connection, procedureName, parameters).ExecuteNonQuery();
        }

        public object ExecuteScalar(string procedureName, DbParameter[] parameters)
        {
            return CreateCommand(Connection, procedureName, parameters).ExecuteScalar();
        }

        public DbDataReader ExecuteReader(string procedureName, DbParameter[] parameters)
        {
            return CreateCommand(Connection, procedureName, parameters).ExecuteReader();
        }

        private DbConnection Connection
        {
            get
            {
                if (connection == null)
                {
                    connection = CreateConnection();
                    connection.Open();
                }
                return connection;
            }
        }

        private static DbConnection CreateConnection()
        {
            var connection = new SqlConnection("data source=blablabla");
            connection.Open();

            return connection;
        }

        private static DbCommand CreateCommand(DbConnection connection, string procedureName, DbParameter[] parameters)
        {
            var dbCommand = connection.CreateCommand();
            dbCommand.CommandType = CommandType.StoredProcedure;
            dbCommand.CommandText = procedureName;
            if (parameters != null)
            {
                dbCommand.Parameters.AddRange(parameters);
            }

            return dbCommand;
        }

        public void Dispose()
        {
            if (connection != null)
            {
                connection.Dispose();
            }
            GC.SuppressFinalize(this);
        }
    }

Код

            using (DbManager dbManager = new DbManager())
            using (DbDataReader dataReader = dbManager.ExecuteReader("GetCathedralsOnFacs", null))
            {
                while (dataReader.Read())
                {
                    Console.WriteLine(dataReader["field"]);
                }
            }

            using (DbManager dbManager = new DbManager())
            {
                dbManager.ExecuteNonQuery("DropDatabase", null);
            }


набросал на глаз прототип, ни на какой базе не тестировал

уродства прибавит создание параметров (кстати, сеттер DbParameter скорее всего сумеет правильно определить DbType, только для null надо будет написать исключение, проверь)
ну и мне не нравится, что не освобождается DbCommand. сделал так, чтобы была возможность вернуть DbDataReader. во всех примерах от MS команды тоже не диспозятся, но это - сомнительное основание поступать так же. здесь обсуждался вопрос

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

Это сообщение отредактировал(а) mihryak - 15.8.2009, 22:45
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0519 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.