EF6 - Code First - Are property mappings needed? - entity-framework

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

Related

how can we control EF Database First generated class and property names

I have an Oracle database that has all its tables and columns in all Upper-Case.
For example table STUDENT has FIRSTNAME,LASTNAME and DATEOFBIRTH
when i generate classes using EF Database First approach, i get all classes and names in Upper-Case as well.
answer here
How to force pascal case with Oracle's Entity Framework support?
did not helped as it only generates names with only First letter in upper case instead of FirstName or LastName.
I thought of doing it manually. Is there a way i can write something in OnModelCreating so that every time i generate edmx i get the names right?
If i change name after generation its going to override next time i update it from database.
ReSharper may be able help with this, though I have not used Re# in a while or the naming convention feature. (see: https://www.jetbrains.com/help/resharper/Inspect_the_Whole_Solution_for_Naming_Style_Compliance.html) Tell it you want UpperCamelCase and run it across the generated code. There may be other plug-ins available with this capability.
EF isn't going to do it as I doubt they'd be trying to determine word boundaries for naming. howwillitknowhowmanywordsareinhere? :)

How to stop EF Core from indexing all foreign keys

As documented in questions like Entity Framework Indexing ALL foreign key columns, EF Core seems to automatically generate an index for every foreign key. This is a sound default for me (let's not get into an opinion war here...), but there are cases where it is just a waste of space and slowing down inserts and updates. How do I prevent it on a case-by-case basis?
I don't want to wholly turn it off, as it does more good than harm; I don't want to have to manually configure it for all those indices I do want. I just want to prevent it on specific FKs.
Related side question: is the fact that these index are automatically created mentioned anywhere in the EF documentation? I can't find it anywhere, which is probably why I can't find how to disable it?
Someone is bound to question why I would want to do this... so in the interest of saving time, the OPer of the linked question gave a great example in a comment:
We have a People table and an Addresses table, for example. The
People.AddressID FK was Indexed by EF but I only ever start from a
People row and search for the Addresses record; I never find an
Addresses row and then search the People.AddressID column for a
matching record.
EF Core has a configuration option to replace one of its services.
I found replacing IConventionSetBuilder to custom one would be a much cleaner approach.
https://giridharprakash.me/2020/02/12/entity-framework-core-override-conventions/
If it is really necessary to avoid the usage of some foreign keys indices - as far as I know (currently) - in .Net Core, it is necessary to remove code that will set the indices in generated migration code file.
Another approach would be to implement a custom migration generator in combination with an attribute or maybe an extension method that will avoid the index creation. You could find more information in this answer for EF6: EF6 preventing not to create Index on Foreign Key. But I'm not sure if it will work in .Net Core too. The approach seems to be bit different, here is a MS doc article that should help.
But, I strongly advise against doing this! I'm against doing this, because you have to modify generated migration files and not because of not using indices for FKs. Like you mentioned in question's comments, in real world scenarios some cases need such approach.
For other people they are not really sure if they have to avoid the usage of indices on FKs and therefor they have to modify migration files:
Before you go that way, I would suggest to implement the application with indices on FKs and would check the performance and space usage. Therefor I would produce a lot test data.
If it really results in performance and space usage issues on a test or QA stage, it's still possible to remove indices in migration files.
Because we already chat about EnsureCreated vs migrations here for completeness further information about EnsureCreated and migrations (even if you don't need it :-)):
MS doc about EnsureCreated() (It will not update your database if you have some model changes - migrations would do it)
interesting too (even if for EF7) EF7 EnsureCreated vs. Migrate Methods
Entity Framework core 2.0 (the latest version available when the question was asked) doesn't have such a mechanism, but EF Core 2.2 just might - in the form of Owned Entity Types.
Namely, since you said:
" I only ever start from a People row and search for the Addresses record; I never find an Addresses row"
Then you may want to make the Address an Owned Entity Type (and especially the variant with 'Storing owned types in separate tables', to match your choice of storing the address information in a separate Addresses table).
The docs of the feature seem to say a matching:
"Owned entities are essentially a part of the owner and cannot exist without it"
By the way, now that the feature is in EF, this may justify why EF always creates the indexes for HasMany/HasOne. It's likely because the Has* relations are meant to be used towards other entities (as opposed to 'value objects') and these, since they have their own identity, are meant to be queried independently and allow accessing other entities they relate to using navigational properties. For such a use case, it would be simply dangerous use such navigation properties without indexes (a few queries could make the database slow down hugely).
There are few caveats here though:
Turning an entity into an owned one doesn't instruct EF only about the index, but rather it instructs to map the model to database in a way that is a bit different (more on this below) but the end effect is in fact free of that extra index on People.
But chances are, this actually might be the better solution for you: this way you also say that no one should query the Address (by not allowing to create a DbSet<T> of that type), minimizing the chance of someone using it to reach the other entities with these costly indexless queries.
As to what the difference is, you'll note that if you make the Address owned by Person, EF will create a PersonId column in the Address table, which is different to your AddressId in the People table (in a sense, lack of the foreign key is a bit of a cheat: an index for querying Person from Address is there, it's just that it's the primary key index of the People table, which was there anyways). But take note that this design is actually rather good - it not only needs one column less (no AddressId in People), but it also guarantees that there's no way to make orphaned Address record that your code will never be able to access.
If you would still like to keep the AddressId column in the Addresses, then there's still one option:
Just choose a name of AddressId for the foreign key in the Addresses table and just "pretend" you don't know that it happens to have the same values as the PersonId :)
If that option isn't funny (e.g. because you can't change your database schema), then you're somewhat out of luck. But do take note that among the Current shortcomings of EF they still list "Instances of owned entity types cannot be shared by multiple owners", while some shortcomings of the previous versions are already listed as addressed. Might be worth watching that space as, it seems to me, resolving that one will probably involve introducing the ability to have your AddressId in the People, because in such a model, for the owned objects to be shared among many entities the foreign keys would need to be sitting with the owning entities to create an association to the same value for each.
in the OnModelCreating override
AFTER the call to
base.OnModelCreating(modelBuilder);
add:
var indexForRemoval = modelBuilder.Entity<You_Table_Entity>().HasIndex(x => x.Column_Index_Is_On).Metadata;
modelBuilder.Entity<You_Table_Entity>().Metadata.RemoveIndex(indexForRemoval);
'''

Entity Framework Pluralization Concern

This is a two part question:
1) What is the advantage of pluralizing other than having model respective tables names implying that they contain a collection of entity records?
2) Pluralizing is a very intricate art, and is sensitive to language localization. When I created an Entity called Schema, EF yielded a table called Schemata.
There is a major problem with this. Primarily, a developer would need to know that the plural of Schema is not Schemas, but the aforementioned. Also, this means that EF maintains some sort of a linguistic dictionary which explicitely dictates pluralization of words, and this can lead to unexpected results..
PS: Ok..., lets have the SO antifa-blm-nazis vote to close my question because it doesn't meet some guidelines, and because they have nothing better to do with their lives, and this commentary is really offensive(albeit true to life)!
Every Entity Framework entity I've ever created I have control over the pluralized version of the name, so I'm not sure what the issue is. You don't have to accept the suggested pluralization. The pluralization is useful in following connections to child entities and their collections, so there is a reason to have them in the first place. Use common sense in creating pluralized names that have the broadest, most easily grasped meaning.

Cannot See Why SQL is Searching a Discriminator Column

After having read a swag of SO questions about the Invalid Column Discriminator, I cannot see why I am running into the issue.
I have reverse-engineered a database Code-First using the EF Power Tools Visual Studio extension.
I have got an include path of "OrderRow.OrderRowOptions.Option" coming off my Orders DbSet. That is,
context.Orders.Include("OrderRow.OrderRowOptions.Option")
There is no Discriminator column on any of the tables and no Discriminator property in any of my POCOs.
The SQL which is being generated and sent to the database includes a Discriminator column.
Why? It's not like they are out of sync. I've repeated the reverse-engineering in a Console app just to make sure of that.
I believe I have finally figured out the problem here.
I always knew from the outset that it was related to EF's treatment of lookup tables.
And I knew that the Table Per Heirarchy ("TPH") feature was in play here.
The bit that I did not realize what that there does not actually need to be a Discriminator column.
I do have a TPH as there is a type called AdditionalLocationsOrderRowOption which inherits from OrderRowOption.
So, even though there is NO Discriminator column in either my database of my domain types (I've verified this countless times), the TPH is coming into play and preventing me from doing the Include on the Orders items.
So, my next step will be to use the Join method of EF-to-entities.

entity framework and database default values workaround

I have to decide about an important item and I need your help.
I'm facing an huge existing database with a lot of default values on nullable columns.
The team has to build a new MVC4 application on top of it (in fact it is a rewrite of old VB6 application).
I (as a consultant) have 'forced' the use of EF5 to get rid of all stored procedures and migrate to a more modern techology.
Now, after my research, it is clear to me that EF5 doesn't support database default values per default. This is why my inserted records are corrupt (they are inserted because the columns are nullable, but with NULL of course).
Some options came up like using the constructor technique, setting the default values in design on the edmx, or playing around with the xml of the edmx.
Despite, these methods are not usefull for us. Where the constructor technique looks ok for me, it is not feasible to do that for all tables in the DB. I also have a 'njet' from the technical person because he wants to maintain these values on 1 place. Same story for setting the default values in design. The database is also not in our scope (read: as less as possible changes to keep existing applications running).
At this point, I'm not sure it EF is the correct choice for our project.
Is somebody aware of (3th party) tools that can fill in the database default values automatically in the generated xml of the edmx file?
Is there som more info about how this xml is build and if there is a possiblity to interfere in the process?
Is there a good readon why these default values should not be taken? Is this going to change in a later release?
Are there other good practices that can be applied to that problem without having all values dupplicated or a massive workload?
Can I arrange something with my poco generator?
I realize there are already a lot of posts of this topic. Too bad, there is no suitable solution for me since we have already something existing and (with all respect) an old VB6 team that I have to convince.
Thanks for your feedback!