MS Access OLEDB провайдер для NET

Все, что вы хотели знать о программизме, но боялись спросить.
Ответить
vg
Маньяк
Сообщения: 2803
Зарегистрирован: 29 май 2003, 22:29
Откуда: Магадан - Миссиссага

MS Access OLEDB провайдер для NET

Сообщение vg »

Всегда доступ был был достаточно быстрый, хоть с использованием ODBC, хоть ADO.
Для провайдера Jet 4.0, для ADO.NET столкнулся с крайне низкой скоростьё выполнения любых операций (выборка, вставка, удаление). Строка соединения такова (VS создаёт в визарде):

Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;Data Source=C:\db.mdb;Mode=Share Deny None;Extended Properties="";Jet OLEDB:System database="";Jet OLEDB:Registry Path="";Jet OLEDB:Engine Type=5;Jet OLEDB:Database Locking Mode=0;Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Global Bulk Transactions=1;Jet OLEDB:Create System Database=False;Jet OLEDB:Encrypt Database=False;Jet OLEDB:Don't Copy Locale on Compact=False;Jet OLEDB:Compact Without Replica Repair=False;Jet OLEDB:SFP=False

Использую OleDbConnection.

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

Как быть (скорость выполнения операций)?

Спасибо.
ПС. С MSSQL работает достаточно быстро.
EAP
Пользователь
Сообщения: 74
Зарегистрирован: 09 ноя 2005, 19:32

Сообщение EAP »

Я думаю визард лишнего понаставил. Посмотри здесь:

http://www.connectionstrings.com/
vg
Маньяк
Сообщения: 2803
Зарегистрирован: 29 май 2003, 22:29
Откуда: Магадан - Миссиссага

Сообщение vg »

EAP писал(а):Я думаю визард лишнего понаставил. Посмотри здесь:

http://www.connectionstrings.com/
Спасибо за реакцию и ссылку. Простые коннекшн стр. я использовал.
Здесь дело в чём-то другом. Что-то косяково. Может в коде моём...
Хотя код простой .... уж некуда проще. Да и с MSSQL работает прекрасно. Сейчас надо что-то прикрутить для юзеров станд-алон версий ... вот и завёлся с MSAcceess. Тем более, что ведь с MSAccess ADO ( без.NET) работало на ура хоть с ODBC провадером, хоть OLEDB...
EAP
Пользователь
Сообщения: 74
Зарегистрирован: 09 ноя 2005, 19:32

Сообщение EAP »

покажи код от строки коннекшина до вывода (как кстати выводишь?).
может чо видно будет.
vg
Маньяк
Сообщения: 2803
Зарегистрирован: 29 май 2003, 22:29
Откуда: Магадан - Миссиссага

Сообщение vg »

EAP писал(а):покажи код от строки коннекшина до вывода (как кстати выводишь?).
может чо видно будет.
I used to use the simplest wrappers coding in C#:

Код: Выделить всё

	public class SimplestAdoNetReader
	{
		OleDbConnection			connection	= null;
		OleDbTransaction		transaction = null;

		OleDbCommand			command		= null;
		OleDbDataReader			reader		= null;
		bool					eof			= true;
		
		string					error		= "";
		bool					msgerror	= true;
		

		public SimplestAdoNetReader()
		{
			connection	= new OleDbConnection();
		}

		private void _prepareCommand( string SQLstr )
		{
			Close();
				
			if ( connection.State == System.Data.ConnectionState.Closed )
				connection.Open();
			
			if ( command != null )
			{
				command.CommandText = SQLstr;
				command.Connection = connection;
			}
			else
				command = new OleDbCommand( SQLstr, connection );
		}

		public void Close()
		{
			if ( reader != null && !reader.IsClosed) 
			{
				reader.Close();
				reader = null;
			}
			if ( connection.State == System.Data.ConnectionState.Open )
				connection.Close();
		}
		
		
		public string ConnectionString
		{
			get
			{
				return connection.ConnectionString;
			}
			set
			{
				if ( connection.State == System.Data.ConnectionState.Open )
					connection.Close();
				connection.ConnectionString = value;
			
			}
		}
		
		public bool Open( string SQLstr )
		{
			try
			{
				_prepareCommand( SQLstr );

				if ( reader == null )
					reader = command.ExecuteReader();

				return true;
			}
			catch(Exception ex)
			{
				error = ex.Message;
				if ( msgerror )
					MessageBox.Show(null, ex.Message, "error reading data");
			}
			return false;
		}


		public bool Read()
		{
			try
			{
				return reader.Read();
			}
			catch(Exception ex)
			{
				error = ex.Message;
				if ( msgerror )
					MessageBox.Show(null, ex.Message, "error reading data");
			}
			return false;
		}

		
		protected bool _integer_field( string fieldname, out int outval)
		{
			try
			{
				if ( ! reader.IsDBNull(reader.GetOrdinal( fieldname ) ))
					outval = reader.GetInt32( reader.GetOrdinal( fieldname ) );
				else 
					outval = 0;
				return true;
			}
			catch(Exception ex)
			{
				error = ex.Message;
				if ( msgerror )
					MessageBox.Show(ex.Message);
			}
			outval = 0;
			return false;
		}

		public int IntegerField( string fieldname )
		{
			int rc = 0;
			_integer_field( fieldname, out rc );
			return rc;
		}


	}
To use this class you could write the code as following:

Somewhere in the main form:

Код: Выделить всё

	public class frmMain : System.Windows.Forms.Form
	{
<skip>
		SimplestAdoNetReader						m_reader = new SimplestAdoNetReader();

…
…
…
And then somewhere:

Код: Выделить всё

		private void frmMain_Load(object sender, System.EventArgs e)
		{
<skip>

			m_reader.ConnectionString = Config.m_dbConnectionString;

			if ( true == m_reader.Open("select id, pubname from pubcommon"))
			{
				while ( m_reader.Read() )
				{
					MessageBox.Show( m_reader.IntegerField( "id").ToString() );
				}
			}
		}
Аватара пользователя
aissp
Маньяк
Сообщения: 2710
Зарегистрирован: 07 ноя 2005, 09:51

угу

Сообщение aissp »

Так и должно быть, когда ты используешь sqlprovider для обращения с сиквел серверу, запросы транслируются в TDS и образаются напрямую к API сиквел сервера

При запросе через оле дб сперва ты вызываешь com объекты ole db слоя который вызывает ком объекты оле дб провайдера который только вызвает апи базы данных.

Сорости различаются в разы (от 2 раз и больше) попробуй поиграться сам организовав доступ через оле к сиквелу.
vg
Маньяк
Сообщения: 2803
Зарегистрирован: 29 май 2003, 22:29
Откуда: Магадан - Миссиссага

Re: угу

Сообщение vg »

aissp писал(а):Так и должно быть, когда ты используешь sqlprovider для обращения с сиквел серверу, запросы транслируются в TDS и образаются напрямую к API сиквел сервера

При запросе через оле дб сперва ты вызываешь com объекты ole db слоя который вызывает ком объекты оле дб провайдера который только вызвает апи базы данных.

Сорости различаются в разы (от 2 раз и больше) попробуй поиграться сам организовав доступ через оле к сиквелу.
Я не могу понять, почему ADO.NET работает с MSAccess хуже (значительно), чем это для неуправляемого кода. Одним маршалингом данных и вызовов неуправляемого кода их управляемого (НЕТ) это не объястнить. Думаю, просто кривось где-то в бизнес логике проекта.
vg
Маньяк
Сообщения: 2803
Зарегистрирован: 29 май 2003, 22:29
Откуда: Магадан - Миссиссага

Re: угу

Сообщение vg »

aissp писал(а): При запросе через оле дб сперва ты вызываешь com объекты ole db слоя который вызывает ком объекты оле дб провайдера который только вызвает апи базы данных.
После первого обращения и вызов COM объект "кешируется" SCM (скорее всего тебе SCM возвратит тоже объект, интерфейсы которых Release. Объект остаёься в памяти некоторое время, даже если никто не AddRef ). Тоже характерно и для соединений, которые были закрыты. Кстати пул соединений был реализовано MS ещё для ODBC.

Я это к тому, что если в НЕТ ничего кординально не ухудшили, то это будут копейки (повторное соединение).
Аватара пользователя
aissp
Маньяк
Сообщения: 2710
Зарегистрирован: 07 ноя 2005, 09:51

Сообщение aissp »

Значит почему доступ к сиквел серверу (к MS SQL Server) через родного провайдера (SqlDataReader) в разы быстрее чем через Ole (OleDbDataReader) тебя понятно :) Я вроде предложил тестик написать и убедиться а не думать типа
vg
Маньяк
Сообщения: 2803
Зарегистрирован: 29 май 2003, 22:29
Откуда: Магадан - Миссиссага

Сообщение vg »

aissp писал(а):Значит почему доступ к сиквел серверу (к MS SQL Server) через родного провайдера (SqlDataReader) в разы быстрее чем через Ole (OleDbDataReader) тебя понятно :) Я вроде предложил тестик написать и убедиться а не думать типа
А причём здесь SqlDataReader :shock:
Там выше я код написал, что использую OleDbDataReader. Для соединений с SQL Server - тоже сервером
Нет там SqlDataReader (и не будет, по условию задачи см.выше и другим причинам) в моём коде.
vg
Маньяк
Сообщения: 2803
Зарегистрирован: 29 май 2003, 22:29
Откуда: Магадан - Миссиссага

Полезно будет не только мне

Сообщение vg »

Как оказалось, по дефолт визард не включает пулинг для Jet.OLEDB провайдера.
Ситуация исправилась (работает очень быстро), если в строке соединения указать явно OLE DB Services=-1 (EnabledAll), или
OLE DB Services=-13 (Default), или OLE DB Services=1(ResourcePooling).

ПС.
1) ADO (не .NET), когда использовался ODBC провайдер, работала хорошо, т.к. настройки пулинга определялись настройками ODBC (вернее ADO просто фактически обёртывает для этого провайдера драйверы ODBC)

2) Всё это представляется немного багом MS. Общепринятая практика такова, что если парамерт, допускающий дефолтовое значение, не указывается, то подразумевается именно дефолт валью.
Т.е. есть если в строке соединения не написано явно...;OLE DB Services=-13;... , то это должно подразумаваться (использование дефолт настройки). Ан нет .... Пока явно не пропишешь "масло масляное" (буквально не напишешь OLE DB Services=-13) - не включается пулинг.
Ответить