i was just trying to achieve a N:M relation between two of my Domain Models with an attribute.
I tried this Tutorial ( sorry, it's german, but the code is fine. ) and everything works fine in the backend and the database (datarecords are created correctly, relations are visible in backend/tca config).
BUT: When I try to create a Model/Repository/Controller/Plugin ( all with minimal basic configurations, just for testing the output, so nothing fancy here ) and try to output my "firma" with the RepositoryMethod->findAll() I get an Error in SQL Syntax.
Extbase seems to access the wrong tables. Normally the SQL statement should ask for the mitarbeiterid/firmaid in the relation table. But the SQL-Error reveals that Extbase tries to find the column "firmaid" / "mitarbeiterid" in the "mitarbeiter"-table, where those columns do not exist.
Does anyone of you know if this can be fixed, or am I missing something from the tutorial (I'm aware that the first tutorial has some typing errors, but that'S not the problem :( ) ? I tried another tutorial IRRE Tutorial which is basically the same, just a bit more extended. Same SQL-Error in here. What has to be done to get some output in the frontend of these datarecords ?
Thanks in advance.
The tutorial seems to be outdated. seems to be more up to date and actually using extbase/fluid.
But lucky you, its not that hard to achieve what you are aiming for. You need to check this list. Make sure that
Your class names, table names and folder structure are in synch with extbase expectations
You have two domain models of which both have a property that contains a objectStorage that contains instances of the other object
You have configured your TCA for both tables to use a mm table for the property containing the objectStorage
Related
Since TYPO3 uses doctrine it is possible to use tables from multiple databases in one instance (with some restrictions like no joins).
But what is possible at all?
At the moment I need two external tables for an extension and instead of using them directly I import them to work locally as usual. But the importing has some draw backs.
Draw backs I can accept:
the data is not live (changes to the external tables are imported later)
the data is read only (changes are done externally anyway)
For importing I use ext:external_import but there are some problems as not all data can be imported in a single run, and then there are errors (e.g. there are reports about duplicate keys, alas there are no duplicate keys in the external tables)
On the other hand I doubt I can use the external tables directly as they have not the usual TYPO3 structure (fields: 'uid', 'pid', 'tstamp', ...). (Maybe they can be mapped in a view?) (of course in the tables I import the data into these fields exist)
Also external changes may be unnoticed and cached content does not reflect current data. In my case that would be a minor problem, as we currently already have no 'live' data, but this needs to be cleaned regularly for cache and for the search index (solr).
What are possible solutions? ? (do they depend on the TYPO3 version?)
What are your experiences?
EDIT:
While trying to realize it considering the given answers more doubts appear:
the tables are readonly (as they are changed from outside):
How do I declare it to TYPO3?
the tables does not follow the usual name rules, especially one table is named sys_category which in this way conflicts with the TYPO3 table sys_category.
Can I build a mapping inside of TYPO3?
Can I build a view from TYPO3 for renaming tables and fields?
like:
CREATE View tx_myext_category
SELECT id as uid, name as title, ...
FROM databasename.sys_category;
Yes, you can fetch data directly from other databases/tables. Of course it highly depends on the usecases and the data you get:
It works fine to read/write data by using the queryBuilder and all the APIs you know from https://docs.typo3.org/m/typo3/reference-coreapi/master/en-us/ApiOverview/Database/Index.html like ConnectionPool, QueryBuilder
If you want to show the data in the formengine, e.g. list module, you will need to have the minimum columns like uid, pid and a valid TCA as well.
From my experience, the mapping mechanism only works if the external table has a almost similar structure as TYPO3 tables. You need at least a uid field on the external side. This cannot be mapped! A missing pid field could be managed with on the TYPO3 side, also crdate or tstamp if needed. Just fill the local data array with the values TYPO3 needs.
Problems arise if you have relations to deal with. Many external systems have other ways to handle relations. You could run into many problems if you try to rely only on the mapping mechanism.
Other problems are fields with date format. Most external tables in the MS world use another format as the unixtime.
If you run into problems with the mapping mechanism you can switch to the TYPO3 queryBuilder. This is a powerful fallback. I experienced problems only with a special type of JOIN statements.
But with the TYPO3 queryBuilder you are on your own. You place instances of the queryBuilder code in the repository and add your model code as usual: thus you can continue to work with Fluid in the frontend as you are used to.
ANSWER TO EDIT:
With the TYPO3 queryBuilder readonly tables aren't a problem. Just don't implement the setter classes in your models.
With TYPO3 queryBuilder you can call any external table with any name. You have full control over the output data in your repository because the mapping is handled inside of it.
As far as I know, there is no way to create SQL views in TYPO3 up to v9, neither with the DBAL mapping mechanism nor with the TYPO3. queryBuilder.
Is there any way to retrieve the column metadata from a query (something like what DbDataReader.GetSchemaTable() does)? I'm basically looking for things like a columns length if it's a string, or if it's a numeric field its precision/scale. This info seems to be lost as it gets projected into a class.
I know you can query the static table metadata, but that doesn't really help me. I also know I can get the DbDataReader if I run an explicit SQL query instead of using LINQ. But I really don't want to do that in this case.
I've been digging through the EF 6 source code and it doesn't look like it exposes this metadata anywhere - but there is a lot going on so it's possible I missed it or didn't think of some way of getting to it.
Any ideas?
I don't know whether to following is possible however I'd like to hear other opinions.
I have an existing database. I will use only certain number of tables and certain columns of those tables. To do that first I created classes and created specific mappings between these classes and database tables. Then implemented DbContext... so far I don't have any problem.
In the second part of the project there are classes which might not exist in the database. So when I run the project if they don't exist I want to implement those, like a normal codefirst implementation however I shouldn't touch other tables in the database.
Any thoughts?
Best
In the second part of the project there are classes which might not exist in the database. So when I run the project if they don't exist I want to implement those, like a normal code first implementation however I shouldn't touch other tables in the database
use Ignore property in your dbcontext, overriding modelbuilder property
modelBuilder.Entity<YourClass>().Ignore();
This will not hamper your database if this class is not mapped in database.
Hope this helps.
I have been reading up on code first approach with entity framework. Unfortunately I can't find much documentation than what relates to EF4 on this. But the docs I have read (scott gu's blog on EF4) indicate that I don't need mappings.
So I generated a code files from an existing database using the EF6 Power Tools this generates all my model classes and a mappings folder. Automatically I looked at the mappings files in there which are using the Fluent API (I think this is correct) and describe details about the tables.
Now reading this makes sense that it possibly wouldn't know the Primary Key, Required Properties, Relationships but the thing I don't get is the Property to Column Mappings from the blog post these were not needed so why do I need them?
I can understand needing them if a column name can't be represented in code but my naming conventions don't allow this.
My main reason for asking is a maintainability question I would rather only have code for a particular property in one place and these lines this.Property(t => t.ID).HasColumnName("ID"); seem redundant to me.
Any one with any helpful links on EF6 code first approach would be appreciated as well google is failing :)
You certainly don't need property mappings if you're satisfied with the default column names and so on. You may need them for things like setting the order of columns in a compound primary key, or specifying that a property contains a database-generated value (like an identity/autoincrement column), but even then you can leave the column names out of it and stick with the defaults.
Column mappings do have some uses, but I'm not sure any of them are relevant to your situation:
You can map your entities to an existing database without having to mimic the column names, which may not follow standard .NET naming conventions.
Similarly, you can follow different naming conventions in your code vs. in your database. For example, where I work, database columns are usually expected to be camelCase, not PascalCase.
They allow you to change the names of your properties at a later date without having to recreate/migrate your database.
If none of those apply to you, then yeah, I think you're probably fine without them.
EF use conventions to do a lot. Once you know and feel comfortable with conventions you can declare classes and things just work.
Code first conventions
I am using EF Code First in a project with an existing Database, all works well and so far I have been creating the class for each table manually (as they have been very small) but getting to the larger tables I can only assume there must be a better way to 'import' or 'convert' the tables fields into a class somehow. Had a search around and can't really find what I'm looking for.
To clarify I want to keep it Code First.
EF Power Tools contains reverse engineer feature for this purpose.