DBIx::Class::Schema::Loader customization - database-schema

We have a MyISAM DB (don't ask me why we don't switch to InnoDB, it is not controlled by me).
Now I want DBIx::Class::Schema::Loader to create relationships for *ID columns adding s to get table names. For example, Order.SeanceID should relate table Order with table Seances.
Can DBIx::Class::Schema::Loader be hacked to do this? Or is it better to write my own Loader?

Don't worry about "hacking" DBIx::Class::Schema::Loader to handle this. Just generate the classes and then add the relationships manually.
Every class that you generate with DBIx::Class::Schema::Loader will contain text at the bottom that looks like this:
# Created by DBIx::Class::Schema::Loader v0.07043 # 2018-07-09 09:56:55
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:6//4n3Crnz9U/q6GZ0Fwtg
# You can replace this text with custom code or comments, and it will be preserved on regeneration
As the last comment says, anything that you insert in the file beneath this text will be preserved if you regenerate the class. So you can safely add the relationship information to this section of the file manually and know that it will still be there the next time you regenerate the class.
Don't forget that you'll need to add both sides of the relationship - for example a has_many relationship in a parent table and the reciprocal belongs_to relationship in the associated child table.

Related

Entity Framework 'Update Model from Database' recreating associations between base and sub classes

I am trying to implement a number of base/sub classes using Entity Framework, database first. Following some online tutorials, I have decided to attempt TPT inheritance.
On the database, I have a base class table 'Location', and two sub class tables: 'StreetAddress' and 'RuralRouteAddress'. I have defined a foreign key constraint between the sub class tables and the base class table on their primary keys. 'Location's Primary Key is an auto-increment column, and the two sub class tables' primary keys are not auto-increment.
In Entity Framework, I defined the 'Base Type' of the two sub classes as 'Location'. I then deleted the associations (and their corresponding navigation properties) from the model. I also deleted the ID column mappings from the sub classes, as ID is now inherited from the 'Location' base class.
This seems to have worked. I haven't tried updating/inserting, but querying returns the data with proper inheritance in place.
My problem is that, whenever I 'Update Model from Database', he inheritance association lines stay, but the FK associations between the base class and the sub classes are brought back... . I then have to delete them, and realign the association lines on my diagram (I'm a bit picky about the layout of the model diagram).
This isn't so bad, but the project that I would like to use TPT inheritance in has a lot of inheritance. Having to delete a ton of associations and reorganize my entire diagram every time I update the model is not very appealing.
Did I do something wrong when I implemented inheritance? Is there a way to ignore/exclude certain associations from being created when updating the model?
The relationships you define in the database will always reappear when you update the model from the database. This is by design. If you want to have classes in the model that have a different relationship structure, try creating a complex model from a stored procedure that selects all the columns (or all the columns you want) from the base table. Import that procedure and in the Function Imports, edit the return type by creating a new complex type, or even just renaming the result that EF automatically creates. Then add your associations on that type, and use it as the base type for your inherited classes.
The good part of this is that you can adjust the type structure to match any table changes by editing the stored procedure, then using "Get Column Information" and "Update" to bring the complex type into line. It won't overwrite your associations because they aren't defined in the database, but it is almost as straightforward as using TPT.
Joey

Entity Framework - Entity not added to design surface

I attempted to update my edmx file by selecting a table. The tool spit out a info message that said the table did not have a primary key.
The entity did not get added to the design surface but it did get added to the .edmx file. In addition, using the model browser I see an Entities.Store and an Entities. My table got added to Entities.Store, but not to Entities.
I cannot access the table that was "added" in the code.
What do I do?
Steps to reproduce:
Create a SQL table with two columns that are both defined as foreign keys to other tables. Make sure the tables that the FKs point to already exist in the model on the design surface.
Right click and choose Update Model from Database...
Next. Under the Add tab, mark the new table under Tables
Click Finish.
An association will be created and it will be selected on the design surface, but it won't start with FK_, it will just be the name of your table. Go to the Model Browser and look under Entity Types. The table will not be there. Look under Associations and you will see your table name there as an association, but it will look out of place (because of the name).
Entity Framework was too smart for me. It created an association instead of an entity. Odd, but it works for how I need to use it.

Create One-to-One relationship based on PK of both tables

I'm really new to Entity Framework (currently using EF5) and vs2012 and am having difficulty trying to figure something out.
I have an .edmx that was generated from my database. It has two tables in it: Item and 3rdPartyItem. In short, the Item table is the main table for all the company items while the 3rdPartyItem table is a table that is used to hold additional attributes for items. This 3rdPartyItem table was created by an outside company and is used with their software for the company, so I can't mess with either table. What I'm trying to do is show a list of Items in a grid but I need to show a combination of all the fields for both tables. In vs2012, if I create a relationship and make it 'zero-to-one' (because for each record in the Item table, there doesn't necessarily have to be one in the 3rdPartyItem table), vs complains about not being mapped correctly. When I set the mapping, it then complains that there's multiple relationships. I did some research and found that you can't create a relationship with 2 primary keys, so I was thinking that was the problem. But how can I change the .edmx so that in code, I can access Items and 3rdPartyItem like so:
var items = dbContext.Items;
items.3rdPartyItem.SomeField <--field from 3rdPartyItem table.
not too sure if it's even possible, but it would be very, very helpful if so. Any ideas?
What you're looking for is table-per-type (TPT) mapping inheritance. You can view an MSDN walkthrough here (although you'd want your base type to be instantiable):
http://msdn.microsoft.com/en-us/data/jj618293.aspx

Plural table names with Entity Frameworks Model First

I'm giving EF Model first a go. I'm using EF 4.1
Pretty much followed this article
I've set PluraliseNewObjects to False on the Model and also in Options->Database Tools ->O/R Designer set Pluralization of names to false.
Neither have any effect - when I generate a new schema from the model the table names are always pluralised - is it possible to disable this?
OK - I've found one way to achieve what I want - but it's a pretty daft route.
Generated db with the plural names (interesting that it only pluralised the tables mapping to types - not the auto-generated linking tables for many to many joins).
Manually renamed the tables in the database
Deleted Model from the project and recreated based on existing database schema (the one I've just renamed).
Model is now correctly mapped to singularly names tables.
I'll wait and see if anyone comes up with a more sensible way of achieving this....
The names of the tables in the generated DDL seem to match the "Entity Set Name" values (different than the "Entity Name"). If you singularize the Entity Set Names, the table names in the DDL are singularized as well.
This will have the possibly undesired effect of singularizing the EntitySet property names in your code, though. Instead of:
myDatabase
.Products
.Where...
.Select...
your code will look like:
myDatabase
.Product
.Where...
.Select...
may or may not be an issue

Where to place auditing fields?

In our shop, when we design a database, we typically include auditing attributes for each table (LastUpdateUser, LastUpdateDate, etc). This is common practice, however, I've noticed this becoming an increasing problem when you have tables that "inherit" from other tables, especially using tools such as the entity framework.
For example, if you have tables Customers and Employees, and those tables have a foreign key to table People, then in your entity / class model when you establish the inheritance, you need to change the names for the audit fields because they exist in both tables. Perhaps they need to become PersonLastUpdatedUser and PersonLastUpdatedDate, while the ones from Employees remain as simply LastUpdatedUser and LastUpdatedDate.
When designing tables for inheritance, do you put such audit fields in both tables, or do you just have them in the parent table and update the parent table whenever an attribute changes in a child table?
If you want to use inheritance than those attributes belong to parent table because the parent with related table forms single entity and you track auditing for whole entity. If you for any reason needs those attributes in both tables it should be the first warning that those tables are not good candidates for inheritance.
If you want true auditing, you create separate audit tables that are populated by triggers (never ever by the application or you will miss items that need to be audited).
and they shouw both the old and new value as well as the date and the user or application that made the change.
If you want a last updatedcolumn in each table (which I think is better than having it only in the parenta as that doesn't tell you anything about which of the tables changes last) and you want o use inheritance then you might need to create unique names by adding the table name to lastUpdated. So PersonLastUpdated and OrderLastUpdated, etc.
Or you don't use inheritance.