Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Программирование в среде .NET (ASP.NET,ADO.NET) на C#/VB.NET

Автор: Solnake
Дата сообщения: 09.01.2008 14:50
Lihonosov
В сторону валидаторов думай.
смотря какую проверку хочеш поставить? По шаблону или еще по чемуто то валидаторы тебе в помощь, а если посложнее - то пиши свой класс проверок.
Автор: Lihonosov
Дата сообщения: 09.01.2008 15:01

Цитата:
смотря какую проверку хочеш поставить? По шаблону или еще по чемуто то валидаторы тебе в помощь

1. Чтобы пользователь не ввел большее количество символов чем нужно.
2. Если пользователь ввел буквы, а разрешено только цифры.
3. Самое непонятное для меня сейчас, как сделать, чтобы если пользователь удаляет строку, кот. является ключом для другой таблицы.
Я так понял нудно переопределить метод Validate???

Добавлено:
На 1. - сделал так - в текстовом поле установил MaxLendth равной максимальному числу допустимых символов.
Автор: Solnake
Дата сообщения: 09.01.2008 15:28

Цитата:
1. Чтобы пользователь не ввел большее количество символов чем нужно.

Правильно зделал.

Цитата:
2. Если пользователь ввел буквы, а разрешено только цифры.

или юзаеш компоненты например девелоперовские или еще какието где в самом компоненте указано что пользователь должон вводить. Или пишеш свой контрол, в котором делаеш такое поле. Или на событие типа онКейАп или еще чето проверяш введенный символ напримет Int.TryParse().
Я бы юзал готовые контролы девелоперов.

Цитата:
3. Самое непонятное для меня сейчас, как сделать, чтобы если пользователь удаляет строку, кот. является ключом для другой таблицы.

Если ты поставиш там все форинкеи то пользователь эту строку не сможет удалить впринцыпе.
Разьве что поставиш каскадное удаление.
А если ты этого не зделаеш, то я не завидую тебе потом когда проект будет работать и ты будеш искать "ну где же тут бага?"

Цитата:
Я так понял нудно переопределить метод Validate???

Может так... Не скажу точно, потому как не юзал.
Скоро буду писать небольшой проект, то подскажу, поскольку буду сам такое делать.
Автор: Lihonosov
Дата сообщения: 09.01.2008 15:57

Цитата:
Я бы юзал готовые контролы девелоперов.

Это что-то наподобие ComponentOne?

Добавлено:

Цитата:
Если ты поставиш там все форинкеи то пользователь эту строку не сможет удалить впринцыпе.

Да я сам для примера пробовал удалять - не удаляет, пишет, что-мол удалить нельзя т.к. с ней связана другая таблица... Меня интересует как вывести пользователю более понятное сообщение, например, "Еще раз так сделаешь - уволю" Чтобы он понял что произошло.
Автор: Solnake
Дата сообщения: 09.01.2008 16:25

Цитата:
Это что-то наподобие ComponentOne?

угу.

Цитата:
Меня интересует как вывести пользователю более понятное сообщение

делаеш удаление в блоке

Код: try
{

}
catch catch (Exception ex)
{
Функция_Вывода_ошибки(ex.Message);
}
Автор: Lihonosov
Дата сообщения: 09.01.2008 16:28
Solnake
СпасибО!!!!!
Автор: Solnake
Дата сообщения: 09.01.2008 16:35
Кстати, вот нашол решение как именно указать что за ошибка.

Код:
try
{

}
catch catch (Exception ex)
{
if (Ex is SqlException && ex.Message.IndexOf("REFERENC") >= 0)
{
Функция_Вывода_ошибки("Еще раз так сделаешь - уволю");
}
else
{
Функция_Вывода_ошибки(ex.Message);
}
}

Автор: Lihonosov
Дата сообщения: 09.01.2008 16:48

Цитата:
Кстати, вот нашол решение как именно указать что за ошибка.

Код:

try
{

}
catch catch (Exception ex)
{
if (Ex is SqlException && ex.Message.IndexOf("REFERENC") >= 0)
{
Функция_Вывода_ошибки("Еще раз так сделаешь - уволю");
}
else
{
Функция_Вывода_ошибки(ex.Message);
}
}

Попробую.
Автор: BlackVetal
Дата сообщения: 10.01.2008 05:25
Lihonosov
У мене только не большое добавление про удаление связанных строк в таблицах: тебе уже посоветовали почитать книги про реляционные БД - не поленись, сделай - если связь между строчками правильно настроить, то тебе будет достаточно удалить одну строчку в главной таблицы, во второстепенных удаление произойдет автоматически ...
Автор: Solnake
Дата сообщения: 10.01.2008 08:51
BlackVetal
Да, каскадное удаление - это все гуд. Но. Каскадное удаление на связь со справочником делать нельзя. Такое ставить можно на связь таблиц типа документ-детализация и т.д.
А то если злоупотреблять каскадным удалением то удалив одну запись из какогото сильно заюзаного справочника можно пол-базы навернуть
Автор: BlackVetal
Дата сообщения: 10.01.2008 09:52
Solnake
Полностью с тобой согласен! поэтому я также как и ты советую Lihonosov почитать книгу про реляционные БД - в таких книгах как раз все подводные камни и описаны!
Автор: Lihonosov
Дата сообщения: 10.01.2008 10:31
Запутался.
Есть три таблицы: Группы поставщиков, Валюты, Имя поставщика.
Есть форма на ней два TextBox и два ComboBox, а также DataGridView.
Два ComboBox связаны каждая со своей таблицей (это "справочники" 1 - валюта, 2 - имя поставщика). DataGridView связана со своей таблицей (Группы поставщиков), в которой всего четыре столбца и два из них это значения: Валюта и Имя поставщика (эти два ComboBox). Остальные два TextBox это значения из DataGridView (соответственно, кот. остались: Имя группы и Коэффициент).
DataGridView используется только для отображения и перемещения по записям, у нее ReadOnly=true.
С занесением всех значений и отображением разобрался (т.е. если в DataGridView переходить по строчкам, то значения меняются и в TextBox и в ComboBox).
C редактированием также все получилось (только со значениями из ComboBox немного повозился, поставил обработчик на DataItemChanged по результату которого значения которые выбраны в ComboBox сразу обновляются в DataGridView, а также поставил обработчик на DataGridView, чтобы если сменялась текущая строка, то в ComboBox значения также менялись).
А вот с добавлением и удалением...
Таблицы связаны ключами, т.е. в таблице "Группы поставщиков" два значения связаны как один ко многим. Одно с таблицей "Валюты" (руб., $...), а другое с "Имя поставщика".
Посоветуете, что-нибудь и вообще я на правильном пути???

Добавлено:
Читать то я читаю, как только есть время.

Добавлено:
Группы поставщиков - PRIMARY KEY --> [Группы поставщиков].[Имя группы]
Валюты - PRIMARY KEY --> Валюты.Валюта
Имя поставщика - PRIMARY KEY --> [Имя поставщика].Имя

[Группы поставщиков].Валюта - Внешний ключ ---> Валюты.Валюта
[Группы поставщиков].[Имя поставщика] - Внешний ключ ---> [Имя поставщика].Имя

Так у меня отношения стоят в самой базе. В DataSet также поставил Relations.
Автор: BlackVetal
Дата сообщения: 10.01.2008 12:34
Lihonosov
1. по поводу связей возможно я что-то недопонял, но я бы зделал связи такие:
Валюта.Код - > Имя_поставщика.Валюта
Группа_поставщиков.Код - > Имя_Поставщика.Группа
2. Добавление записи в гриде:
На событие "добавление" вешаеш обработку, которая собирает необходимые данные для параметров запроса (ну обычно введенная строка) и передаеш их. В самом запросе добавления сначала проверяеш наличие переданных значений справочников Валюта и Группа поставщика через обычный Select. Если все значения имеются в справочниках добавляеш полученные параметры в таблицу Имя постащика.
Автор: Lihonosov
Дата сообщения: 10.01.2008 13:28

Цитата:
Валюта.Код - > Имя_поставщика.Валюта
Группа_поставщиков.Код - > Имя_Поставщика.Группа

В таблице "Группа поставщиков" есть четыре поля:
Например:

Группа Имя пост. Валюта прайса Коэффициент
Канцелярия ЧП Канцопт грн. 1,2
Промтовары ООО "ОГО" $ 1,15
...

Цитата:
В самом запросе добавления сначала проверяеш наличие переданных значений справочников Валюта и Группа поставщика через обычный Select. Если все значения имеются в справочниках добавляеш полученные параметры в таблицу Имя постащика.

Проверять ненужно, т.к. это значения из ComboBox, которые пользователь выбирает, а не вводит. А нужно проверить "Группа" и "Коэффициент"


Добавлено:
Я пробовал так:
На "ДОБАВИТЬ" я вставляю строку:
sqlDataAdapter1.InsertCommand.Parameters["@Группа"].Value="NEW";
sqlDataAdapter1.InsertCommand.Parameters["@Коэффициент"].Value=1;
sqlDataAdapter1.InsertCommand.Parameters["@Валюта"].Value="руб."; //валюта по умолчанию
sqlDataAdapter1.InsertCommand.Parameters["@Имя поставщика"].Value=""; //можно NULL

sqlConnection1.Open();
sqlDataAdapter.InsertCommand.ExecuteNonQuery();
sqlConnection1.Close();

DataSet1.Clear();
sqlDataAdapter.Fill(DataSet1);
(пишу по памяти, так что могут быть ошибки)

Но выдает ошибку, точно не помню, что в таблице не может быть два одинаковых значения в "Группа". Но я точно знаю, что в таблице нет группы с названием "NEW"?!?!?

Приведенный выше код работает у меня на других таблицах, например "Валюта", "Единицы измерения"..., т.е. где только один PRIMARY KEY и нет внешних ключей.
Может есть какая-то особенность добавления строк в таблицу, которая содержит внешние ключи???
Автор: BlackVetal
Дата сообщения: 10.01.2008 14:08
Lihonosov
Тогда получается что связь будут такие:
Валюта.Код - > Группа_поставщика.Код_Валюты
Имя_Поставщика.Код - > Группа_поставщика.Код_постащика
Т.е. таблица "валюта" состоит например из 2 столбов: код, имя валюты.
"Имя поставщика" - код, имя поставщика
в таблице "Группа поставщиков" следующие поля: группа, код_поставщика, код_валюты и коэффициент.

По поводу проверок тебе по-любому нужно сначала проверить наличие в справочниках значений КОДА валюты и КОДА поставщика

По поводу ошибки выложи пожалуйста еще sql запрос ... по коду C# вроде в порядке ...
Автор: Lihonosov
Дата сообщения: 10.01.2008 14:33

Цитата:
Тогда получается что связь будут такие:
Валюта.Код - > Группа_поставщика.Код_Валюты
Имя_Поставщика.Код - > Группа_поставщика.Код_постащика
Т.е. таблица "валюта" состоит например из 2 столбов: код, имя валюты.
"Имя поставщика" - код, имя поставщика
в таблице "Группа поставщиков" следующие поля: группа, код_поставщика, код_валюты и коэффициент.

Абсолютно верно

Цитата:
По поводу проверок тебе по-любому нужно сначала проверить наличие в справочниках значений КОДА валюты и КОДА поставщика

А зачем делать проверку введенных значений из ComboBox, ведь в ComboBox значения из таблиц "Валюты" и "Имя поставщика"???
Цитата:
По поводу ошибки выложи пожалуйста еще sql запрос ... по коду C# вроде в порядке ...

На форме у меня три адаптера:
1. Для DataGridView - SELECT * FROM [Группы поставщиков]
2. ComboBox - тот, кот. Валюта SELECT * FROM Валюты
3. ComboBox - тот, кот. имя поставщика. SELECT * FROM [Имя поставщика]
И DataSet в котором хранятся результаты этих запросов и установлены Relations.
Автор: BlackVetal
Дата сообщения: 11.01.2008 05:14
Lihonosov
в адаптерах должны быть команды вставки, обновления и удаления данных - попробуй их настроить: есть два варианта - либо писать запрос в адаптере (минус в том если ты захочеш изменить запрос, то придеться компилировать приложение заново), либо писать в адаптере sql-процедуру (естесно изменения вносяться на sql сервере и компилировать ничего не нужно). я обычно пользуюс вторым вариантом.
И чаще всего структуру приложения такая - есть отдельный проект, в котором храняться данные, выбираются из БД, записываются и т.д., на выходе получается .dll . а второй проект непосредственно формы, которые юзают уже .dll .
Автор: Solnake
Дата сообщения: 11.01.2008 08:51
BlackVetal
Аналогично делаю проекты.

Для работы с базой есть классы приблезительно такой структуры

Код:
public class TemplateRelationDALC: DALCBase
{
#region Properties

private int _TVID;
private int _TOTVID;
private int _RID;
private ViewRelationDALC _SelfRelations;

public int TVID
{
get { return _TVID; }
set { _TVID = value; }
}

public int TOTVID
{
get { return _TOTVID; }
set { _TOTVID = value; }
}

public int RID
{
get { return _RID; }
set { _RID = value; }
}

public ViewRelationDALC SelfRelations
{
get
{
if (_SelfRelations==null)
{
_SelfRelations = ViewRelationDALC.Get(RID, Transaction);
}
return _SelfRelations;
}
set { _SelfRelations = value; }
}

#endregion

#region Constructors

public TemplateRelationDALC(int _TVID, int _TOTVID, int _RID, SqlTransaction p_Transaction)
: base(p_Transaction)
{
this._TVID = _TVID;
this._TOTVID = _TOTVID;
this._RID = _RID;
}

public TemplateRelationDALC(int _TVID, int _TOTVID, int _RID)
{
this._TVID = _TVID;
this._TOTVID = _TOTVID;
this._RID = _RID;
}

#endregion

public override int Save()
{
StProcedure.ProcedureName = "rb_TemplateRelation_Save";
StProcedure["@ID"].Direction = ParameterDirection.InputOutput;
StProcedure["@ID"].Value = ID;
StProcedure["@TVID"].Value = _TVID;
StProcedure["@TOTVID"].Value = _TOTVID;
StProcedure["@RID"].Value = _RID;
StProcedure.ExecuteNonQuery();
int tmpID = (int)StProcedure["@ID"].Value;
if (tmpID>0)
SetID(tmpID);
return ID;
}

#region Get

public static TemplateRelationDALC Get(int id, SqlTransaction p_Transaction)
{
StoredProcedure sp = new StoredProcedure("rb_TemplateRelation_Select", p_Transaction);
sp["@ID"].Value = id;
sp["@TVID"].Value = DBNull.Value;
sp["@TOTVID"].Value = DBNull.Value;
DataReader dr = sp.ExecuteReader();
try
{
if (dr.Read())
{
TemplateRelationDALC dalc =
new TemplateRelationDALC(dr.GetInt32("TVID"), dr.GetInt32("TOTVID"), dr.GetInt32("RID"),
p_Transaction);
dalc.SetID(dr.GetInt32("TRID"));
return dalc;
}
return null;
}
finally
{
dr.Close();
}
}

public static TemplateRelationDALC Get(int id)
{
return Get(id, null);
}

public static TemplateRellationCollection GetAll(int tvid, SqlTransaction p_Transaction)
{
StoredProcedure sp = new StoredProcedure("rb_TemplateRelation_Select", p_Transaction);
sp["@ID"].Value = DBNull.Value;
sp["@TVID"].Value = tvid;
sp["@TOTVID"].Value = DBNull.Value;
DataReader dr = sp.ExecuteReader();
try
{
TemplateRellationCollection collection = new TemplateRellationCollection();
while (dr.Read())
{
TemplateRelationDALC dalc =
new TemplateRelationDALC(dr.GetInt32("TVID"), dr.GetInt32("TOTVID"), dr.GetInt32("RID"),
p_Transaction);
dalc.SetID(dr.GetInt32("TRID"));
collection.Add(dalc);
}
return collection;
}
finally
{
dr.Close();
}
}

#endregion

public void Delete()
{
StProcedure.ProcedureName = "rb_TemplateRelation_Delete";
StProcedure["@ID"].Value = ID;
StProcedure.ExecuteNonQuery();
}

}
Автор: Lihonosov
Дата сообщения: 11.01.2008 09:30
BlackVetal
Solnake
Спасибо Вам.
Со вставкой и удалением разобрался.
У меня было три адаптера и один DataSet, в кот. три таблицы. Когда я вставлял строку, то после всего очищал датасет и снова заполнял, чтобы добавленная строка отобразилась в датагриде. НО! Адаптера три, а поновому заполненных датасет после добавления был заполнен от одного адаптера, а про остальные два??? Т.е. вконце процедуры добавления строки и очистки датасет, нужно было :
sqlDataAdapter1.Fill(DataSet1);
sqlDataAdapter2.Fill(DataSet1);
sqlDataAdapter3.Fill(DataSet1);
или для этих двух адаптеров создать свой датасет.

Добавлено:
А еще у меня на OnLoad формы стоит:
int row;
row=DataGridView1.CurrentCell.RowIndex;
ComboBox1.SelectedValue=DataSet1.[Группы поставщиков].[row].gname;
ComboBox2.SelectedValue=DataSet1.[Группы поставщиков].[row].gval;
Т.е. чтобы в комбобоксах выделялись значения, кот. в текущей строке датагрида. Такие же строки стоят на кликмыши про строке грида и на KeyUp.
Автор: BlackVetal
Дата сообщения: 11.01.2008 09:44
Lihonosov
я чесно скажу уже не помню работу со стандартными компонентами ... но помоему нужно делать команду fill для Dataset, а не для адаптера ...
я уже давно работаю с компонентами из библиотеки ComponentOne - для мене это лучший вариант для работы с БД ...
Автор: Lihonosov
Дата сообщения: 11.01.2008 09:59

Цитата:
я чесно скажу уже не помню работу со стандартными компонентами ... но помоему нужно делать команду fill для Dataset, а не для адаптера ...

DataAdapter.Fill Method

Adds or refreshes rows in the DataSet to match those in the data source using the DataSet name, and creates a DataTable named "Table".
[Visual Basic]
Public MustOverride Function Fill( _
ByVal dataSet As DataSet _
) As Integer Implements IDataAdapter.Fill
[C#]
public abstract int Fill(
DataSet dataSet
);
[C++]
public: virtual int Fill(
DataSet* dataSet
) = 0;
[JScript]
public abstract function Fill(
dataSet : DataSet
) : int;
С msdn.microsoft.com

Цитата:
я уже давно работаю с компонентами из библиотеки ComponentOne - для мене это лучший вариант для работы с БД ...

Я ставил себе как-то CоmponentOne на VisualStudio 2005 и были ужастные тормоза, но это было на старом компе (Celeron 2,53, 512 ОЗУ). Сейчас работаю на компе (Core2Duo 2Ghz, 2Gb ОЗУ) и Visual Studio 2008 TeamSuite.
Как ComponentOne с VisualStudio2008?
Автор: Solnake
Дата сообщения: 11.01.2008 10:45
Lihonosov
1. Тебе нада эта Visual Studio 2008 TeamSuite?
Ставь себе простую студию 2005 и лучше поставь себе на нее ReSharper, пользы будет больше. Тем более что 2008 насколько я знаю делалась для 3-го фреймфорка.
2. Компоненты тормозить среду разработки не должны впринцыпе. Сам экзешник делать тяжелее могут, а как на саму студию они влияют - хз как у тебя такое получилось.
3. Я пользуюсь еще со времени писания на делфе DevExpress. Просто шас фирма не хочет покупать их под НЕТ, а буржуи не хотят чтобы им писали с украденными компонентами, то приходится рисовать кучу своих контролов. Но это под веб.
А свои проекты, что пишу дома - юзаю везде DevExpress. Грида более удобного чем у него не видел нигде.
Автор: Lihonosov
Дата сообщения: 11.01.2008 10:57

Цитата:
Ставь себе простую студию 2005 и лучше поставь себе на нее ReSharper, пользы будет больше. Тем более что 2008 насколько я знаю делалась для 3-го фреймфорка.

В ней когда создаешь проект, то выбираешь какой фреймфорк хочешь использовать.
Сегодня попробую поставить ReSharper и ComponentOne на 2008.
Автор: Solnake
Дата сообщения: 11.01.2008 11:31
Lihonosov
Просто к чему я клоню - к тому что
1. в 2005 баг меньше потому как она старше и много чего в ней исправляли.
2. 2008 - глюкавая и с решарпером приготовся к частым вылетам и АВ непонятно почему. На небольших проектах - может и все гуд, на больших - такое будет постоянно.

Но это так... совет просто. Принцыпиальной разницы нету в какой студии писать. Главное чтобы сама среда была стабильная, чем 2008 не отличается, хотя кто как хочет так и ....
Автор: Lihonosov
Дата сообщения: 11.01.2008 12:12

Цитата:
к частым вылетам и АВ непонятно почему

АВ-?
Автор: BlackVetal
Дата сообщения: 11.01.2008 12:36
Lihonosov

Цитата:
Как ComponentOne с VisualStudio2008?

вполне нормально. тем более недавно было обновление компонент ...

по поводу DataAdapter.Fill Method - прошу прощения не прав - заработался с компонентами ComponentOne - там как раз наоборот делается Dataset.Fill

Solnake

Цитата:
2008 - глюкавая и с решарпером приготовся к частым вылетам и АВ непонятно почему. На небольших проектах - может и все гуд, на больших - такое будет постоянно

Чесно сказать не очень долго работаю на vs2008 в паре с TFS2008... Проект не скажу что совсем большой ( командой пишем второй год ERP-систему) да и на маленький уже давно не тянет. Пока глюкоф не замечено ...
Автор: Solnake
Дата сообщения: 11.01.2008 13:14

Цитата:
АВ-?

Access Violation
А может и другая ошибка, не помню точно, но от этого не легче, вылеты есть.

Цитата:
Пока глюкоф не замечено ...

У нас один проект где только файлов работы с БД - 500 штук. Я уже молчу о контролах, веб-формах и т.д.
При чем все написано по всем канонам ООП.
Так вот, в 2008 пробовал работать, и вернулся назад на 2005.
Автор: Lihonosov
Дата сообщения: 11.01.2008 15:17
А есть информация по использованию ComponentOne?
Автор: BaluBig
Дата сообщения: 12.01.2008 11:30
Solnake

Цитата:
Так вот, в 2008 пробовал работать, и вернулся назад на 2007.

Странно. У меня ситуация полностью противоположная. Перенес проект с 2003 на 2005 - матерился чуть не каждый день, глюк на глюке и глюком погоняет. Выход 2005 SP1 ситуацию практически не улучшил (что они там патчили на 400Мб и почти час установки?). Переехал на 2008 где-то в октябре - претензий нет.

Добавлено:
Lihonosov
Ну там же хелп есть наверняка
Автор: Solnake
Дата сообщения: 12.01.2008 13:06
Хм...
Ну прям так у всех работает нормально, а у меня нет... Заставило задуматся....
Качаю Microsoft Visual Studio 2008 Team Suite ENU, буду еще раз пробовать. Возможно и придется поменять свое мнение...

Страницы: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102

Предыдущая тема: Как удалить/добавить/отключить/включить устройство?


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.