Динамическое добавление OleDBConnection в DataSources
Динамическое добавление OleDBConnection в DataSources
Добрый день.
Подскажите пожалуйста, возможно ли программно добавить имеющийся OleDBConnection в список DataSources. Если возможно, приведите небольшой пример.
Заранее спасибо.
Подскажите пожалуйста, возможно ли программно добавить имеющийся OleDBConnection в список DataSources. Если возможно, приведите небольшой пример.
Заранее спасибо.
Динамическое добавление OleDBConnection в DataSources
Спасибо за вопрос.
Вы можете передать имеющийся OleDbConnection через report.RegData();
Пример:
Код: Выделить всё
System.Data.OleDb.OleDbConnection connection =
new System.Data.OleDb.OleDbConnection(
"Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;Data Source=" + StiConfig.ApplicationDirectory + "\\Nwind.mdb");
report.RegData("NorthWind", connection);
Спасибо.
Динамическое добавление OleDBConnection в DataSources
Еще один вопрос, в каком массиве хранятся все зарегистрированные соединения? Как получить к ним доступ?
Динамическое добавление OleDBConnection в DataSources
Зарегистрированные подключения к базам данных хранятся в коллекцииBeraleX писал(а):Еще один вопрос, в каком массиве хранятся все зарегистрированные соединения? Как получить к ним доступ?
report.Dictionary.Databases
Базовый класс для этой коллекции - StiDatabase.
Спасибо.
Динамическое добавление OleDBConnection в DataSources
Извините, но почему тогда при выполнении кода
Report.Dictionary.Databases.Clear();
Report.RegData("test", DBConnection);
ReportStream.Seek(0, SeekOrigin.Begin);
Report.LoadDocument(ReportStream);
Report.Design();
в дизайнере отображаются предидущие Dataconection и этот под названием "test". По идее должен быть только он один.
Кроме того при сохранении файла из потока (поток из БД) его размер меньше на один байт чем у оригинала. Может что то не так в коде?
Другие BLOB поля этим кодом сохраняются без проблем.
OleDbDataReader myReader = ReadReport.ExecuteReader(CommandBehavior.SequentialAccess);
ReportStream = new MemoryStream();
bw = new BinaryWriter(ReportStream);
myReader.Read();
startIndex = 0;
retval = myReader.GetBytes(0, startIndex, outbyte, 0, bufferSize);
while (retval == bufferSize)
{
bw.Write(outbyte);
bw.Flush();
startIndex += bufferSize;
retval = myReader.GetBytes(0, startIndex, outbyte, 0, bufferSize);
}
bw.Write(outbyte, 0, (int)retval - 1);
bw.Flush();
FileStream outStream = File.OpenWrite(exportReportFile.FileName);
ReportStream.WriteTo(outStream);
Report.Dictionary.Databases.Clear();
Report.RegData("test", DBConnection);
ReportStream.Seek(0, SeekOrigin.Begin);
Report.LoadDocument(ReportStream);
Report.Design();
в дизайнере отображаются предидущие Dataconection и этот под названием "test". По идее должен быть только он один.
Кроме того при сохранении файла из потока (поток из БД) его размер меньше на один байт чем у оригинала. Может что то не так в коде?
Другие BLOB поля этим кодом сохраняются без проблем.
OleDbDataReader myReader = ReadReport.ExecuteReader(CommandBehavior.SequentialAccess);
ReportStream = new MemoryStream();
bw = new BinaryWriter(ReportStream);
myReader.Read();
startIndex = 0;
retval = myReader.GetBytes(0, startIndex, outbyte, 0, bufferSize);
while (retval == bufferSize)
{
bw.Write(outbyte);
bw.Flush();
startIndex += bufferSize;
retval = myReader.GetBytes(0, startIndex, outbyte, 0, bufferSize);
}
bw.Write(outbyte, 0, (int)retval - 1);
bw.Flush();
FileStream outStream = File.OpenWrite(exportReportFile.FileName);
ReportStream.WriteTo(outStream);
Динамическое добавление OleDBConnection в DataSources
а зачем ты пишешь -1
bw.Write(outbyte, 0, (int)retval - 1); ???
да и bw.Flush(); можно не делать теле цикла
Вот мой код который работает:
private bool GetReport()
{
if (_Report != null)
return true;
using (FbDataReader dr = cDBUtils.ExecuteReader("SELECT NAME, DESCRIPTION, SOURCE FROM REP_REPORTS WHERE ID = " + _ID.ToString()))
{
dr.Read();
Report = new StiReport();
if (dr.IsDBNull(2)) //Создание
{
Report.ReportName = dr.GetString(0);;
if (!dr.IsDBNull(1))
Report.ReportDescription = dr.GetString(1);
}
else //Загрузка
{
MemoryStream ms = new MemoryStream();
BinaryWriter writer = new BinaryWriter(ms);
long retVal;
long startIndex = 0;
int bufferSize = 1024;
byte[] outByte = new byte[bufferSize];
try
{
retVal = dr.GetBytes(2, startIndex, outByte, 0, bufferSize);
writer.Write(outByte, 0, Convert.ToInt32(retVal));
while (retVal == bufferSize)
{
startIndex += bufferSize;
retVal = dr.GetBytes(2, startIndex, outByte, 0, bufferSize);
writer.Write(outByte, 0, Convert.ToInt32(retVal));
}
writer.Flush();
ms.Seek(0, SeekOrigin.Begin);
Report.LoadPackedReport(ms);
}
catch (Exception ex)
{
MessageBox.Show("Ошибка загрукзи отчета: " + ex.Message);
return false;
}
finally
{
writer.Close();
}
}
Report.ReportFile = Path.Combine(Application.StartupPath, SysBase.Consts.Organization + " - " + ReportName + ".mrt");
}
return true;
}
Можно было бы улучшить следующее: при загрузке отчета сразу создавать объект отчета, а не сначала новый отчет и потмо вызывать для него метод загрузки.
ReportFile устанавливаю для того что бы при вызове сохранения вызывалась команда СОХРАНИТЬ а не СОХРАНИТЬ КАК
bw.Write(outbyte, 0, (int)retval - 1); ???
да и bw.Flush(); можно не делать теле цикла
Вот мой код который работает:
private bool GetReport()
{
if (_Report != null)
return true;
using (FbDataReader dr = cDBUtils.ExecuteReader("SELECT NAME, DESCRIPTION, SOURCE FROM REP_REPORTS WHERE ID = " + _ID.ToString()))
{
dr.Read();
Report = new StiReport();
if (dr.IsDBNull(2)) //Создание
{
Report.ReportName = dr.GetString(0);;
if (!dr.IsDBNull(1))
Report.ReportDescription = dr.GetString(1);
}
else //Загрузка
{
MemoryStream ms = new MemoryStream();
BinaryWriter writer = new BinaryWriter(ms);
long retVal;
long startIndex = 0;
int bufferSize = 1024;
byte[] outByte = new byte[bufferSize];
try
{
retVal = dr.GetBytes(2, startIndex, outByte, 0, bufferSize);
writer.Write(outByte, 0, Convert.ToInt32(retVal));
while (retVal == bufferSize)
{
startIndex += bufferSize;
retVal = dr.GetBytes(2, startIndex, outByte, 0, bufferSize);
writer.Write(outByte, 0, Convert.ToInt32(retVal));
}
writer.Flush();
ms.Seek(0, SeekOrigin.Begin);
Report.LoadPackedReport(ms);
}
catch (Exception ex)
{
MessageBox.Show("Ошибка загрукзи отчета: " + ex.Message);
return false;
}
finally
{
writer.Close();
}
}
Report.ReportFile = Path.Combine(Application.StartupPath, SysBase.Consts.Organization + " - " + ReportName + ".mrt");
}
return true;
}
Можно было бы улучшить следующее: при загрузке отчета сразу создавать объект отчета, а не сначала новый отчет и потмо вызывать для него метод загрузки.
ReportFile устанавливаю для того что бы при вызове сохранения вызывалась команда СОХРАНИТЬ а не СОХРАНИТЬ КАК
Динамическое добавление OleDBConnection в DataSources
Спасибо, все работает, но не столкнулся с проблемой - когда загружаю отчет из базы в дизайнер или просмотр - он пустой, если тот же отчет сохраняю на винт а потом загружаю в дизайнер - показывает и тип дпнных, и источник данных, и сам сформированный отчет!? В чем дело, значит источник данных все таки сохраняется в теле отчета?
Динамическое добавление OleDBConnection в DataSources
Необходимо уточнить мой предыдущий пост.
report.Dictionary.Databases содержит коллекцию соединений самого отчета. Эта коллекция записывается вместе с отчетом.
report.Dictionary.DataStore содержит коллекцию данных (реальных). В нее попадают данные двумя способами:
1. Из вне. Через метод RegData
2. Из отчета. Все удачные соединения из отчета также попадают сюда.
Перед построением отчета, каждый источник данных производит поиск в этой коллекции по DataName.
Эта коллекция не сохраняется вместе с отчетом (и по определению не можем быть сохранена).
Спасибо.