To the point; is there any way to customize the pluralization service for database-first EF models?
Specifically, I'd like to use the *Set suffix notation, wherein the entity sets and collection navigation properties are named accordingly:
User to UserSet
Report to ReportSet
etc.
I know I've seen this made possible with code-first, however I'm stuck with database-first as the development process.
I'm aware of IPluralizationService, but can't figure out how to substitute my custom implementation.
Currently, I'm manually working through the entity sets and collection properties in the model browser (VS2015) and appending "Set" to each of them; this is fine to do once, however whenever I regenerate the model it becomes quite the pain in my ass.
Any suggestions?
You could write something that will update the edmx file to the new names.
Also I was going to suggest you could alter the t4 script (the .tt files) but I think that will break the mapping with the edmx file in a database first situation.
But I think you should reconsider code first, you can use the code first generator multiple times, just clean out the context class, and the connection string in the config and make a new context that is named the same (it will overwrite the table classes). You can nuget EntityFramework.CodeTemplates.CSharp and alter the t4 templates that it downloads to include "Set" and that is what it will use to generate the classes.
And then you don't fall into edmx hell, edmx files are a pain once you start trying to maintain them instead of letting them just be what is generated.
I ended up writing a script (PHP of all things) to perform XML transformations on the EDMX file. I lose support for some of the more obscure features due to the way the transformation is performed, however it was the only way I could do it without sacrificing kittens to an omniscient force. Most importantly, it maintains the mappings as expected.
I couldn't figure out a way to work the transformation script into the generation pipeline yet; though I may look at invoking it from the text template.
I'm aware that the question and its answers are 4 years old, but:
In EF6 you can implement a pluralization convention, and replace the default English pluralization with your own.
The original implementation uses a convention, which calls a service. I'm not sure whether you can simply register a service for IPluralizationService in the DependencyResolver, but you can definitely write your own convention.
The only warning is that the GitHub code relies on internal methods which you need to copy/substitute, e.g.
var entitySet = model.StoreModel.Container.EntitySets.SingleOrDefault(
e => e.ElementType == GetRootType(item));
replacing original
model.StoreModel.GetEntitySet(item);
and the method GetRootType().
Related
There is a WPF application that is currently transitioning from Entity Framework 6 to Entity Framework Core 5 (database provider is Oracle, the application uses .NET 5 so EF Core 6 isn't possible currently).
There is one big issue to solve: two scaffolded data types weren't correct (from bool to byte and from bool to int). I changed those types manually. If I now re-scaffold, those changes will be removed for sure.
So my question: is there any possibility to re-scaffold (using the -force parameter) without losing the manually changed types OR is there any possibility to override the types which will be generated by scaffolding?
In Entity Framework 6, we used custom data type on EDMX creation to solve this issue:
What I tried and missed: creating a partial class with the same class name (but different file name) which only contained my changes.
The reason why I'm not using migrations is that I use different database stages.
Thanks for your help!
What I tried and missed: creating a partial class with the same class name (but different file name) which only contained my changes.
This will work with the caveat that when the db is re-scaffed the new entities will have the same props appear again (but wrongly typed) and if they're also defined in your partial class you'll get a compile error due to two members having the same name
I'd recommend you install EFCore Power Tools extension and use it to scaff (Reverse Engineer) because there's a section of the "wizard" where it asks you which things you want to scaff and you can untick those columns in the DB to omit them from the models. If they take part in some relationship or have atypical properties meaning they get special attention in the fluent config then you might have to consider an alternative strategy that I use a lot; scaff to a different folder and then run a diff tool to help you merge changes into the main model, then delete the new scaff set.
I leave myself comments in the context that "is the main one", such as "//do not remove this enum column config during context merge", having set up some fluent blah that I know will not be present in the new scaffing
EFCPT does also have some abilities to customize the generated code but I don't know if it goes as far as entirely rewriting parts (I've never looked). It's open source so you can also look at modifying it to meet your needs
Let's say I have a project where I use Entity Framework, but I want to use my own classes instead of the EF classes.
Reasons for using my own classes:
Easy to add properties in code
Easy to derive and inherit
Less binding to the database
Now, my database has table names like User and Conference.
However, In my domain project, I also call my files User.cs and Conference.cs.
That means I suddenly have two objects with the same naming, which is usually very annoying to work with, because you have to use namespaces all the time to know the difference.
My question is how to solve this problem?
My ideas:
Prefix all database tables with 'db'. I usually do this, but in this case, I cannot change the database
Prefix or postfix all C# classes with "Poco" or something similar
I just don't like any of my ideas.
How do you usually do this?
It's difficult to tell without more background but it sounds like you are using the Entity Framework designer to generate EF classes. This is known as the "Model First" workflow. Have you considered using the Code First / Code Only workflow? When doing code first you can have POCO classes that have no knowledge of the database, EF, or data annotations. The mapping between the database and your POCOs can be done externally in the the DBContext or in EntityTypeConfiguration classes.
You should be able to achieve your goal of decoupling from EF with just one set of objects via code first.
To extend the above answer, the database table name User (or Users as many DB designers prefer) is the identifier for the persistence store for the object User that's defined in your code file User.cs. None of these identifiers share the same space, so there should be no confusion. Indeed, they are named similarly to create a loose coupling across spaces (data store, code, development environment) so you can maintain sanity and others can read your code.
I'm trying to create a project from scratch. I'll be using asp .net mvc4 (with asp net web api), and entity framework 5 for data access (all the latest technologies)
Since it's a fresh start, I was thinking on centering my design on my model rather than creating the database first and then creating the EF model, so I though I'd go with a code first approach.
The problem with code first (as far as I see) is that you lose all the scaffolding that EF does for you on a model first scenario (design support, easily generating and maintaining entity relationships 1-1, 1-*, -, etc)
The question is : What tools or templates or snippets or whatever can I use to make my life easier when designing my model?. I want this process to be as painless as possible, since it involves a lot of repetition (FK relationships, for example, are the same always)
Should I use DbContext or something else? Is there some kind of way to start code first but at the same time maintain an edmx model, or those are mutually exclusive?
thanks!
The great thing about EF Code First is that you don't need any scaffolding. You don't need an EDMX model, you don't even need to specify the exact nature of relationships, it's all based on conventions. For example your classes must have a property called Id, which will be taken to be the Primary Key of the table. All string based fields are generated as nvarchar(MAX). Of course some conventions might not be what you want and Code First supports this through pluggable conventions (you can remove most conventions and create your own)
You should do some of the basic tutorials to get an idea of how the Code First flow works as it's an entirely different proposition to the Db First approach.
I'm starting a new application that must use an existing database that use some naming conventions that are really annoying in .net (table names start with several trigrams that specify the business domain of the table, column names start with the tables trigram, trigrams are in uppercase and separated by underscores, etc.,).
What I'd like to do is to write a simple renaming rule (this is as simple as finding the last underscore and take everything after that) and apply it in Entity Framework. I don't really want to edit the names one by one in the editor, especially because the database might change and I don't want to do it several times.
I'm using Database First (as the database already exists and it is "the master"), and EF 4.x DbContext Generator and it works really great out of the box (with badly named classes and properties though).
I edited the T4 templates in order to rename the generated entities and properties, but when I try to perform any request, the DbContext object can't find the table that matches with the entity I'm trying to request and I get this exception :
The entity type [Entity Name] is not part of the model for the
current context.
This is obvious why it doesn't find the table : nothing tells it how to match the entity name and the table as I changed it on the fly.
I read that I can add instructions in the OnModelCreating(DbModelBuilder modelBuilder) method but this is not used in Database First (and the default T4 template adds an exception in it, just in case).
So now I'm stuck, I don't know how to specify that matching.
Here are several ideas I have but not sure if it's correct or doable :
Using the "plural / singular" API to change the name of the Entity ? Sounds like a dirty workaround. But it might work (didn't try though).
Finding a way to edit the EDMX file on the fly.
Editing the EDMX afterwards but it might complicate the process (edit in the designer, then execute a tool to alter the EDMX, then run custom tool to regenerate entities and DbContext... while today I just have to edit in the designer).
Using Code First (as it seems easier to use different entity names than table names, through attributes or instructions in the DbContext class), but it sounds like it would not be more complicated to use it with an existing database.
Any idea ? Or did I miss something ?
You won't be able to use a T4 transform for this, as you want to change the content of the actual .edmx file to map your store entity names (with the obnoxious prefixes) to your sanitized conceptual entity names.
Instead, you're better off writing an application that takes an .edmx file as input and sanitizes the names under the conceptual model tag and modifies the mapping names to reflect the sanitized names. I understand that this is your third option and that you wanted to avoid this if possible, but this is the most straightforward way to go about it. Bear in mind that you'll only have to run this tool when you add new tables or columns.
One of the specifications for an application I'm developing is that it must work with project files.
My problem comes into how I'm going to fulfill this requirement because, since I'm working toward making the application as loose as possible using Prism and Unity, I can't decide on which implementation I'm going to use for the project files creation and managing (project files loading, saving, etc).
The application is going to be a SEO helper and will mostly handle text information, like Uri's and strings it will fetch from internet.
I thought of some possible implementations using:
a - The framework System.Configuration namespace. This was my first option, since I could easily plug new ConfigurationSection's into the Configuration object. The downside is that it leaves no opportunity (or at least I couldn't figure how) for using interfaces for abstraction.
b - Create a database for each project and save it in a file. With this implementation I could use a database framework such as nHibernate or any other (open to suggestions) to handle the object-to-db mapping.
c - Add your own here.
My question is, what do you guys think would be the better approach to handle different configuration/settings for every module that I plug into it and for persisting big lists of urls, lists of about 10k~100k urls as long with other settings?
Thanks in advance!
The simplest way will be to define your own type (class) like ProjectSettings { ... } and simply have it serialized/deserialized with the preferred serializer (XML for example).
Then you simply don't need any fancy ORMs or configurations.
Don't introduce complexity where you don't need it ;)
Configuration file is a good solution when you have few dozen configuration variables (
But here, it 's better to have database.Why? Because if you want to do some modification on 10-100k uri, it will be hard and error will be easy.
With a database (one table for project, another for string connections, another for uri..), it will be easy to query it, update it, CRUD it.
you have to use database when data are to big for a file in this case because of relationship between entities (one project have many string connection, many uri...)
For ORM, Entity Framework 4.0 because it is POCO (no metadata on entities class mapped).
Best regard