Entity Framework Pluralization Concern - entity-framework

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.

Related

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 Code First unique constraint across multiple tables

So I'm creating a database model using Entity Framework's Code First paradigm and I'm trying to create two tables (Players and Teams) that must share a uniqueness constraint regarding their primary key.
For example, I have 3 Players with Ids "1", "2" and "3" and when I try to create a Team with Id "2", the system should validate uniqueness and fail because there already exists a Player with Id "2".
Is this possible with data annotations? Both these entities share a common Interface called IParticipant if that helps!
Txs in advance lads!
The scenario you are describing here isn't really ideal. This isn't really a restriction on Entity Framework; it's more a restriction on the database stack. By default, the Id primary key is an Identity column, and SQL itself isn't really supportive of the idea of "shared" Identity columns. You can disable Identity and manage the Id properties yourself, but then Entity Framework cannot automatically build navigation properties for your entities.
The best option here is to use one single participant table, in a technique called "Table Per Hierarchy", or TPH. Entity Framework can manage the single table using an internal discriminator column. Shared properties can be put into the base class, and non-shared properties can be put on the individual classes, which Entity Framework will composite into a single large table in the DB. The main drawback to this strategy is that columns for non-shared properties will automatically be nullable in the database. This article describes this scenario very well.
The more I try to come up with a solution, I realize that this is an example of the XY Problem. There is not really a good solution to this question, because this question is already a proposed solution. There is a problem here that has led you to create an Interface which you suggest requires the entities which are using the interface to have a unique Id. This really sounds like an issue with the design of the Interface itself, as Interfaces should be agnostic to the entity they are applied to. Perhaps providing some code and showing what your problem actually is would be helpful, since the proposed solution you are asking how to implement here isn't really practical.

EF6 - Code First - Are property mappings needed?

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

Entity Framework TPC with multiple inheritance

I am using EF with TPC and I have a multiple inheritance lets say I have
Employee (abstract)
Developer (inherits from Employee)
SeniorDeveloper (inherits from Developer)
I inserted some rows in the database and EF reads them correctly.
BUT
When I insert a new SeniorDeveloper, the values get written to the SeniorDeveloper AND Developer database table, hence querying just the Developers (context.Employees.OfType()) also gets the recently added SeniorDevelopers.
Is there a way to tell EF, that it should store only in one table, or why does EF fall back to TPT strategy?
Since it doesn't look like EF supports the multiple inheritance with TPC, we ended up using TPC for Employee to Developer and TPT between Developer and SeniorDeveloper...
I believe there is a reason for this, although I may not see the full picture and might just be speculating.
The situation
Indeed, the only way (that I see) for EF to be able to list only the non-senior developers (your querying use-case) in a TPT scenario by reading only the Developer table would be by using a discriminator, and we know that EF doesn't use one in TPT/TPC strategies.
Why? Well, remember that all senior developers are developers, so it's only natural (and necessary) that they have a Developer record as well as a SeniorDeveloper record.
The only exception is if Developer is an abstract type, in which case you can use a TPC strategy to remove the Developer table altogether. In your case however, Developer is concrete.
The current solution
Remembering this, and without a discriminator in the Developer table, the only way to determine if any developer is a non-senior developer is by checking if it is not a senior developer; in other words, by verifying that there is no record of the developer in the SeniorDeveloper table, or any other subtype table.
That did sound a little obvious, but now we understand why the SeniorDeveloper table must be used and accessed when its base type (Developer) is concrete (non-abstract).
The current implementation
I'm writing this from memory so I hope it isn't too off, but this is also what Slauma mentioned in another comment. You probably want to fire up a SQL profiler and verify this.
The way it is implemented is by requesting a UNION of projections of the tables. These projections simply add a discriminator declaring their own type in some encoded way[1]. In the union set, the rows can then be filtered based on this discriminator.
[1] If I remember correctly, it goes something like this: 0X for the base type, 0X0X for the first subtype in the union, 0X1X for the second subtype, and so on.
Trade-off #1
We can already identify a trade-off: EF can either store a discriminator in the table, or it can "generate one" at "run time".
The disadvantages of a stored discriminator are that it is less space efficient, and possibly "ugly" (if that's an argument). The advantages are lookup performance in a very specific case (we only want the records of the base type).
The disadvantages of a "run time" discriminator are that lookup performance is not as good for that same use-case. The advantages are that it is more space efficient.
At first sight, it would seem that sometimes we might prefer to trade a little bit of space for query performance, and EF wouldn't let us.
In reality, it's not always clear when; by requesting a UNION of two tables, we just lookup two indexes instead of one, and the performance difference is negligible. With a single level of inheritance, it can't be worse than 2x (since all subtype sets are disjoint). But wait, there's more.
Trade-off #2
Remember that I said the performance advantage of the stored-discriminator approach would only appear in the specific use-case where we lookup records of the base type. Why is that?
Well, if you're searching for developers that may or may not be senior developers[2], you're forced to lookup the SeniorDeveloper table anyway. While this, again, seems obvious, what may be less obvious is that EF can't know in advance if the types will only be of one type or another. This means that it would have to issue two queries in the worst case: one on the Developer table, and if there is even one senior developer in the result set, a second one on the SeniorDeveloper table.
Unfortunately, the extra roundtrip probably has a bigger performance impact than a UNION of the two tables. (I say probably, I haven't verified it.) Worse, it increases for each subtype for which there is a row in the result set. Imagine a type with 3, or 5, or even 10 subtypes.
And that's your trade-off #2.
[2] Remember that this kind of operation could come from any part of your application(s), while the resolving the trade-off must be done globally to satisfy all processes/applications/users. Also couple that with the fact that the EF team must make these trade-offs for all EF users (although it is true that they could add some configuration for these kinds trade-offs).
A possible alternative
By batching SQL queries, it would be possible to avoid the multiple roundtrips. EF would have to send some procedural logic to the server for the conditional lookups (T-SQL). But since we already established in trade-off #1 that the performance advantage is most likely negligible in many cases, I'm not sure this would ever be worth the effort. Maybe someone could open an issue ticket for this to determine if it makes sense.
Conclusion
In the future, maybe someone can optimize a few typical operations in this specific scenario with some creative solutions, then provide some configuration switches when the optimization involves such trade-offs.
Right now however, I think EF has chosen a fair solution. In a strange way, it's almost cleaner.
A few notes
I believe the use of union is an optimization applied in certain cases. In other cases, it would be an outer join, but the use of a discriminator (and everything else) remains the same.
You mentioned multiple inheritance, which sort of confused me initially. In common object-oriented parlance, multiple inheritance is a construct in which a type has multiple base types. Many object-oriented type systems don't support this, including the CTS (used by all .NET languages). You mean something else here.
You also mentioned that EF would "fallback" to a TPT strategy. In the case of Developer/SeniorDeveloper, a TPC strategy would have the same results as a TPT strategy, since Developer is concrete. If you really want a single table, you must then use a TPH strategy.

Any decent resources on how to map complex POCO objects in EF 4.1?

So I heard L2S is going the way of the dodo bird. I am also finding out that if I use L2S, I will have to write multiple versions of the same code to target different schemas even if they vary slightly. I originally chose L2S because it was reliable and easy to learn, while EF 3 wasn't ready for public consumption at the time.
After reading lots of praises for EF 4.1, I thought I would do a feasibility test. I discovered that EF 4.1 is a beast to get your head around. It is mindnumblingly complex with hundreds of ways of doing the same thing. It seems to work fine if you're planning on using simple table-to-object mapped entities, but complex POCO object mapping has been a real PITA. There are no good tutorials and the few that exist are very rudimentary.
There are tons of blogs about learning the fundamentals about EF 4.1, but I have a feeling that they deliberately avoid advanced topics. Are there any good tutorials on more complex mapping scenarios? For instance, taking an existing POCO object and mapping it across several tables, or persisting a POCO object that is composed of other POCO objects? I keep hearing this is possible, but haven't found any examples.
Disclaimer: IMO EF 4.1 is best known for its Code-First approach. Most of the following links point to articles about doing stuff in code-first style. I'm not very familiar with DB-First or Model-First approaches.
I have learned many things from Mr. Manavi's blog. Especially, the Inheritance with code-first series was full of new stuff for me. This MSDN link has some valuable links/infos about different mapping scenarios too. Also, I have learned manu stuff by following or answering questions with entity-framework tags here on SO.
Whenever I want to try some new complex object mapping, I do my best (based on my knowledge about EF) to create the correct mappings; However sometimes, you face a dead end. That's why god created StackOverflow. :)
What do you mean by EFv4.1? Do you mean overhyped code-first / fluent-API? In such case live with a fact that it is mostly for simple mapping scenarios. It offers more then L2S but still very little in terms of advanced mappings.
The basic mapping available in EF follows basic rule: one table = one entity. Entity can be single class or composition of the main class representing the entity itself and helper classes for set of mapped fields (complex types).
The most advanced features you will get with EF fluent-API or designer are:
TPH inheritance - multiple tables in inheritance hierarchy mapped to the same table. Types are differed by special column called discriminator. Shared fields must be in parent class.
TPT inheritance - each type mapped to the separate table = basic type has one table and each derived type has one table as well. Shared fields must be defined in base type and thus in base table. Relation between base and derived table is one-to-one. Derived entities span multiple tables.
TPC inheritance - each class has separate table = shared fields must be defined in base type but each derived type has them in its own table.
Entity splitting - entity is split into two or more tables which are related by one-to-one relation. All parts of entity must exist.
Table splitting - table is split into two or more entities related with one-to-one relation.
Designer also offers
Conditional mapping - this is not real mapping. It is only hardcoded filter on mapping level where you select one or more fields to restrict records which are allowed for loading.
When using basic or more advanced features table can participate only in one mapping.
All these mapping techniques follow very strict rules. Your classes and tables must follow these rules to make them work. That means you cannot take arbitrary POCO and map it to multiple tables without satisfying those rules.
These rules can be avoided only when using EDMX and advanced approach with advanced skills = no fluent API and no designer but manual modifications of XML defining EDMX. Once you go this way you can use
Defining query - custom SQL query used to specify loading of new "entity". This is also approach natively used by EDMX and designer when mapping database view
Query view - custom ESQL query used to specify new "entity" from already mapped entities. It is more usable for predefined projections because in contrast to defining query it has some limitations (for example aggregations are not allowed).
Both these features allow you defining classes combined from multiple tables. The disadvantage of both these mapping techniques is that mapped result is read only. You must use stored procedures for persisting changes when using these techniques.