问题
I have a datamodule with a TFDConnection connecting to a SQLLite db.
Queries on the datamodule work fine. But if I have a query on a form connecting to the connection on the datamodule when setting Active to true I get the error:
exception message : [FireDAC][Comp][Clnt]-512. Connection is not defined for [FDQuery1]. Possible reason: Connection and ConnectionName property values
This happens in design time.
This is with Delphi Tokyo in a Firemonkey mobile app.
回答1:
I think this may be a FireDAC (or IDE) bug which has been introduced between Delphi Seattle an Tokyo (10.2). I found I could reproduce it as follows:
Create a new multi-device (FMX) project in Seattle.
Add a datamodule to the project and add an FDConnection to it. I configured the FDConnection to use the MSSQL driver, set the connection to use OS Authentication, my local Sql Server and an existing db on it. I set LoginPrompt to false.
I added FDQuery1 to the form, made the form USE the datamodule's unit, then set FDQuery1's connection to the one on the datamodule and added "select * from mytable" as its Sql. Then I set FDQuery1.Active to true in the OI. FDQuery1 opened without complaint. I reset FDQuery1.Active to false, saved the project and closed it.
I closed Seattle, started Tokyo and opened the project. When I set FDQuery1.Active to true, I got the exact same exception message as you have reported. Interestingly, the OI then updates FDQuery1.Active to display
True
.I then set FDQuery1.Active to false then true, and the exception did not occur.
I closed and restarted Tokyo, re-opened the project and, again, the first time (but only the first time) I set FDQuery1.Active to true, the exception occurs again.
You are welcome to include the above steps in a problem report to Emba. Btw, I didn't spend any time investigation the run-time behaviour of the project.
At a guess - and it is only a guess - there is a problem somewhere in the IDE which manifests when it has to create an instance of the datamodule so that it's FDConnection can establish the connection needed to open FDQuery1. If that's right, it shouldn't affect the run-time behaviour but like I say, I have not investigated that. If I'm right, I think it's more of an annoyance than a major problem.
Update: This problem seems to be FMX-specific. I repeated steps 1-3 in a new Tokyo VCL project and the exception + error message does not occur, even the first time FDQuery1.Active is set to true.
Update#2: This problem is easily reproducible at run-time. All you need to do is to remove the datamodule from the Project's Forms | AutoCreate list and then, at run-time, attempt to open the FDQuery before the datamodule has been created. Obviously, the work-around is simply to check that the datamodule exists before opening the FDQuery and, if not, to create it in code.
Btw, in a real-world application, personally I wouldn't rely on a TDataSet's Active property setting in the IDE to open the dataset, and always open it in code instead. It's a habit I got into in the early years of Delphi, when there often seemed to be problems with design-time settings of datasets and datasources which referred to a db connection or similar located in another module being "lost" at run-time.
回答2:
I was getting this same bug using Delphi 10.3 Community Edition in Windows VCL Application. Even though my FDQuery has a valid connection.
I found out in the Embarcadero Delphi CE Bootcamp 2018 course Week 4 of Databases that the problem is because your DataModule was created after your Form.
To fix that you should go to:
Project --> Options --> Application --> Forms
In Autho-create forms you should notice this sequence:
- Form1
- DataModule1
And you should change the order so DataModule is first:
- DataModule1
- Form1
In case your connection is placed in the DataModule, you must first connect your connection and then after activated your query. Your query can not be activated before your connection is connected.
- Connect in your connection (This can be done in the DataModule);
- Activate the query (Let's say it is in your MainForm).
If you create the form before your DataModule, the query will accuse that there is no connection, because the datamodule connection was not created yet.
You also can change the sequence of the created forms programmatically in Project --> View Source.
Check the following code.
program FDSearchInst;
uses
Vcl.Forms,
UnitMain in 'UnitMain.pas' {FormMain},
UnitDataPaths in '..\SharedFiles\UnitDataPaths.pas',
UnitDataModule in '..\SharedFiles\UnitDataModule.pas' {SharedDM: T};
{$R *.res}
begin
ReportMemoryLeaksOnShutdown := True;
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TSharedDM, SharedDM); // Will be created first
Application.CreateForm(TFormMain, FormMain); // Will be created after
Application.Run;
end.
In this code, you may also notice a problem I have been through. There is a comment {SharedDM: T}
in front of the DataModule path which is a way to assign a name for your DataModule (when you access the Application --> Forms you will see this name).
This name SharedDM
must be different from the file name UnitDataModule
, otherwise, it will cause conflict and you'll not be able to run your project.
To explain better, check the following code:
Correct
UnitDataModule in '..\SharedFiles\UnitDataModule.pas' {SharedDM: T};
Incorrect
UnitDataModule in '..\SharedFiles\UnitDataModule.pas' {UnitDataModule: T};
来源:https://stackoverflow.com/questions/46601409/issue-with-tfdquery-on-a-form-connecting-to-a-datamodule