Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Базы данных и репортинг > FireDAC неверное отбражение Lookup field


Автор: Beltar 1.4.2015, 11:19
XE6 Build 20.0.15596.9843
В общем столкнулся с тем, что при редактировании таблицы в dbgrid для Lookup-поля после Insert отображается первое значение из связанной таблицы еще до того, как его ввели. На ADO проблема отсутствует. Тестовый проект с простейшей базой.

Автор: Beltar 1.4.2015, 11:20
Выглядит вот так:

Автор: Beltar 1.4.2015, 11:21
База (MS SQL 2008R2)

Автор: Alexeis 1.4.2015, 11:38
Цитата(Beltar @  1.4.2015,  12:19 Найти цитируемый пост)
В общем столкнулся с тем, что при редактировании таблицы в dbgrid для Lookup-поля после Insert отображается первое значение из связанной таблицы еще до того, как его ввели.

  Честно говоря, я всегда думал, что Lookup нельзя редактировать (вводить через DBGrid). Ведь Insert ты делаешь для текущего датасета, а Insert для Lookup поля расположен в другом датасете. Соответственно, нужно переводить в режим Edit не основной датасет, а связанный. Тут наверняка могут быть особенности по настройке самих датасетов. По крайней мере нужно проверить что при переводе DBGrid-а в режим редактирования зависимый датасет тоже перейдет в режим edit. Если не так, то нужно курить маны по фаредаку на предмет связанных датасетов. 

Автор: Beltar 1.4.2015, 13:55
Я же не лукап редактирую, а поле вместо которого этот лукап отображается (Id_завода). т лукапа требуется толкьо список допустимых значений отображать. Обычная техника со времен появления Delphi.

Автор: superVad 1.4.2015, 15:00
Beltar, просто интересно, а можно отказаться от лукап поля и просто присоединить нужную таблицу в запросе?
Я в доставшемся мне проекте так и сделал со всеми лукап полями. Сильно оно все усложняло и работало порой странно.

Автор: Alexeis 1.4.2015, 15:51
Цитата(Beltar @  1.4.2015,  14:55 Найти цитируемый пост)
Я же не лукап редактирую, а поле вместо которого этот лукап отображается (Id_завода). т лукапа требуется толкьо список допустимых значений отображать

  Тогда причина может скрываться в запросе select dataseta из которого делается lookup. У меня обычно не было проблем, если этот датасет не имеет связи с мастер датасетом в котором выводится лукап поле. Т.е. нет отношений master-detail у основного датасета и того из которого делается lookup.

Автор: Beltar 1.4.2015, 15:58
А пользователям тогда показывать неизвестное им число Id? Не думаю, что они это оценят.

Автор: Alexeis 1.4.2015, 16:03
Цитата(Beltar @  1.4.2015,  16:58 Найти цитируемый пост)
А пользователям тогда показывать неизвестное им число Id? Не думаю, что они это оценят. 

  Насколько я понял, что для работы механизма lookup связь master-detail не нужна. Датасеты сами разбираются меж собой, что откуда брать. Если не поможет, то можно попробовать раскидать их даже на разные транзакции. Не исключено, что перевод главного датасета в режим edit автоматически закрывает транзакцию, которую использует 2й датасет. 
Я с фаредаком не работал, так что могу предполагать только по общей схеме DataSet/DataSource/DBGrid.

Автор: Beltar 1.4.2015, 16:08
Все связи там, обычный Foreign Key в базе.
Заводы:
Id:Int PK
Название:Varchar

Оборудование:
Id:Int PK
Id_Завода:Int FK к Заводы.Id
Название: Varchar
Lookup Завод: String через Id_Завода к Заводы.Id

Больше в Delphi ничего не делается, Master-detail не формируется.

Все, что мне нужно, работать с понятным названием завода вместо его Id. Это делали на автомате еще в эпоху BDE. Оно же мне зачем-то показывает сразу после инсерта первую строку из заводов, еще до того, как пользователь что-то выбрал.

Да, можно ес-но выбрать нужный завод, и оно все нормально запишется, но, если пользователя отображаемый пункт устраивает, он просто нажмет сохранить и получит эксепшен, что Id_Завода required.

Автор: Alexeis 2.4.2015, 10:31
Цитата(Beltar @  1.4.2015,  17:08 Найти цитируемый пост)
Оно же мне зачем-то показывает сразу после инсерта первую строку из заводов, еще до того, как пользователь что-то выбрал.

  Слушай, а может там (в таблице) ID завода имеет дефолтное значение и при инсерте автоматически проставляет дефолт? Я бы еще поковырял транзакции. Чтобы не вышло ситуации что зависимый датасет сбрасывается. Или может запрос refresh неверно сформирован. Т.е. для этой строки делает refresh и он подставляет что-то.

Автор: Beltar 2.4.2015, 12:26
Неа.

Код

USE [FDTest]
GO

/****** Object:  Table [dbo].[Заводы]    Script Date: 04/02/2015 10:53:34 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[Заводы](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Название] [varchar](50) NOT NULL,
 CONSTRAINT [PK_Заводы] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO


Код

USE [FDTest]
GO

/****** Object:  Table [dbo].[Оборудование]    Script Date: 04/02/2015 10:53:41 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[Оборудование](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Название] [varchar](50) NOT NULL,
    [id_Завода] [int] NOT NULL,
 CONSTRAINT [PK_Оборудование] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[Оборудование]  WITH CHECK ADD  CONSTRAINT [FK_Оборудование_Заводы] FOREIGN KEY([id_Завода])
REFERENCES [dbo].[Заводы] ([Id])
GO

ALTER TABLE [dbo].[Оборудование] CHECK CONSTRAINT [FK_Оборудование_Заводы]
GO


Запустил SQL-профайлер, но как и ожидалось TDataset.Insert отрабатывает исключительно на клиенте, и пока Post не вызовут, никаких обращений к серверу не происходит, что логично. Тут у TFDQuery какая-то непонятка, что он не NULL возвращает.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)