Change entities and properties names in Database First - c#

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.

Related

Entity Framework 6, Database-First & Custom Pluralization

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().

Is it possible to use Entity Framework and keep object relations in the code and out of the database

I'm having a hard time just defining my situation so please be patient. Either I have a situation that no one blogs about, or I've created a problem in my mind by lack of understanding the concepts.
I have a database which is something of a mess and the DB owner wants to keep it that way. By mess I mean it is not normalized and no relationships defined although they do exist...
I want to use EF, and I want to optimize my code by reducing database calls.
As a simplified example I have two tables with no relationships set like so:
Table: Human
HumanId, HumanName, FavoriteFoodId, LeastFavoriteFoodId, LastFoodEatenId
Table: Food
FoodId, FoodName, FoodProperty1, FoodProperty2
I want to write a single EF database call that will return a human and a full object for each related food item.
First, is it possible to do this?
Second, how?
Boring background information: A super sql developer has written a query that returns 21 tables in 20 milliseconds which contain a total of 1401 columns. This is being turned into an xml document for our front end developer to bind to. I want to change our technique to use objects and thus reduce the amount of hand coding and mapping from fields to xml (not to mention the handling of nulls vs empty strings etc) and create a type safe compile time environment. Unfortunately we are not allowed to change the database or add relationships...
If I understand you correct, it's better for you to use Entity Framework Code First Approach:
You can define your objects (entities) Human and Food
Make relations between them in code even if they don't have foreign keys in DB
Query them usinq linq-to-sql
And yes, you can select all related information in one call.
You can define the relationships in the code with Entity Framework using Fluent API. In your case you might be able to define your entities manually, or use a tool to reverse engineer your EF model from an existing database. There is some support for this built in to Visual Studio, and there are VS extensions like EF Power Tools that offer this capability.
As for making a single call to the database with EF, you would probably need to create a stored procedure or a view that returns all of the information you need. Using the standard setup with lazy-loading enabled, EF will make calls to the database and populate the data as needed.

Editing T4 files to customize entity class names and output file names

I'm using Entity Framework Reverse Engineer Code First on an existing database. The classes are created properly but I need to change the entity names. I want to prefix every entity class with "EpiFlex". If a SQL table name is Users, the resulting entity should be EpiFlexUsers and the output file should be EpiFlexUsers.cs.
Is there a tag of some sort that I can add to the beginning of the T4 files to have that prefix added automatically or do I have to painstakingly go through each file and put the prefix ahead of the auto generated code?
Or maybe I'm totally missing the point. Is there another way to specify custom naming of the entities?
There doesn't seem to be any quick and easy way to do this. However, Programming Entity Framework 2nd Edition is an excellent book that I've come to consider absolutely essential if you're going to really get into entity framework. This book also has a lot of help on editing the T4 files. I haven't digested the complete section on T4 editing yet so maybe I'll still find something that shows how to very easily do what I want.
Here is a link to the book. http://shop.oreilly.com/product/9780596807252.do

Entity Framework conflict with same table name from different databases

I am using Entity Framework 4 with MVC 3 in Visual Studio 2012 (C#).
I am using database first; there are two separate databases each with its own namespace and with two separate edmx files. Each database has a table with the same name and fields (but different content). When I added the second table I started to get compile errors.
Ambiguity between 'Interface.CodeFormStatus.FormStatusCodeID'
and 'Interface.CodeFormStatus.FormStatusCodeID'
There seem to be some complex workarounds or I could rename one of the tables. Is there not a straightforward solution as this must be a fairly common issue.
I ran into a situation where I had two databases (one an older version of the other) and I needed to integrate both into a single project. Naturally, almost every name conflicted.
I created two separated edmx files for each database, and put each in its own namespace for clarity. I then edited each entity name to reflect which database it was coming from - (e.g. "Activities", which was in both, became "v13Activities" and "v14Activities").
For operations which were to be mirrored between both databases, I wrote a wrapper that included both contexts. This made my code was much less repetitive, and it had less synchronization issues.
Hope this approach helps someone else - it seems like this is an obscure question, and this answer was one of the top results on Google!
Update: In EF 6.1+, there is another solution. You can have "conflicting" names, and separate them with simple namespacing when using the "Code First From Database" option. I would advocate for this solution going forward, as the old XML .edmx style is going to be phased out starting in EF Core.
This worked for me. Just click on the table in the designer (the graphical version not the code) Then in the properties next to the, "Name" attribute you can change the name to something different. This will just change the name within the designer and used more as an alias throughout the application.
If you don't have many tables with the same name, then you could edit entity name in designer (your .edmx file).
So, just double-click a name of one of your CodeFormStatus entities and make it different (for example, change it to CodeFormStatusOther)

How can I use the EntityModelSchemaGenerator to generate less then my entire model?

We have a big (and growing!) database. We're trying to not have to build the models by hand, and we found this
EdmGen2 which is supposed to build our EDMX entity models for us.
Since we have such a big database we'd like to not have all of our tables in the same Model. We got it all to work, but the generated model has all of our tables.
There is a read only list of the tables inside of the EntityStoreSchemaGenerator. It is (in fact) all of our tables.
Will this tool make a model that is less then our full database? Can we select which tables we want to put it and only use those?
The EdmGen2 code comes with an option called /RetrofitModel. The key point of this mode is that is runs some data mining algorithms to see if there are any obvious inheritance-like relationships in the database instance, and if so, generates an EDMX that includes those inheritances.
However, another feature of the /RetrofitModel option is that it allows one to select tables. For instance, if one has the AdventureWorks sample database, you can issue this statement:
EdmGen2 /RetrofitModel "Server=(local);Integrated Security=true;Initial Catalog=AdventureWorks;" "System.Data.SqlClient" "AVWorks"
It will bring up a list of the tables in the database, at which point you can check which ones you want to have in your model.
The tupleFraction parameter helps define what it means to be a "significant" subclass. The data mining rules are heuristics, and as such they can potentially find patterns where common sense might not agree.
The tupleFraction parameter says this (for some of the rules): if EdmGen++ thinks that it has found a subclass, but the new subclass has less than tupleFraction of the instances from its parent class, consider the new subclass "insignificant" and don't create it. The parameter is optional - if you don't specify it, I think that it gets set to 0.05 (5%).
The current version only allows table specification through the UI. However, to pull the list of tables from a file or from some other source is an easy addition - I will add it to the top of the to-do list for the next version.
UPDATE: We have updated the code at code.msdn.microsoft.com/edmgen2 to allow for tables to be specified without the GUI. In the previous version, the RetrofitModel option would bring up a dialog that would allow the user to choose the tables to include in the model. The ConceptualEdmGen dll now has two additional public methods that can set the list of tables without bringing up a dialog – one that pulls the list of tables from a file, and one where the list of tables is fed directly to the method as a list of strings.
The EdmGen2 code as it appears in the package uses the “from file” option, where it looks for a file called “Tables.txt” in the current directory, and if found, feeds its contents to the dll to set the list of tables. So for instance, if the following were the contents of the file “Tables.txt”:
HumanResources.Department
HumanResources.Employee
HumanResources.EmployeeAddress
HumanResources.EmployeeDepartmentHistory
HumanResources.JobCandidate
HumanResources.Shift
EdmGen2 would generate (for the RetrofitModel option) a model for all of the tables in the HumanResources schema for AdventureWorks. For both methods, an empty list will result in all tables in the database being added to the model. The table selection UI will still appear if neither table selection method is called.
I've just sent an email to the guy responsible for EdmGen2 lets see what he comes back with
Alex James
Program Manager, Entity Framework Team, Microsoft.
My solution to this was to create a variant of EdmGen2 which reads a Filters.txt file that contains not just table names, but text that gets parsed into EntityStoreSchemaFilterEntry parameters (Category, Schema, Name, ObjectType, FilterEffect). This allows me to generate models and assemblies which operate on specific views as well as tables - something that I don't think EdmGen2 does.
Of course that doesn't work with the ConceptualEdmGen, but since there is no source available for that I've elected not to use that component anyway.
One problem that I haven't solved is how to properly inject function definitions for stored procs into CSDL and MSL. I have it in SSDL but don't know yet how to do the others.

Categories

Resources