I want to add Entity Framework 5 database first into a class library in Visual Studio 2012 targeting .net framework 4.5. I am confused with all the labels I need to key in:
The EDMX file name when adding ADO.NET entity data model to the project. I put ‘MyEF.edmx’.
When saving the connection string into the config file. I put ‘MyEntities’.
After selecting some tables to include in my model, there’s a textbox to input model namespace. I put ‘MyModel’.
Property ‘custom tool namespace’ of the MyEF.edmx file. I put ‘TheEF’.
Property ‘custom tool namespace’ of the MyEF.Context.tt file. I put ‘TheContext’.
Property ‘custom tool namespace’ of the MyEF.tt file. I put ‘TheModel’.
Opening MyEF.edmx with ADO.NET entity data model designer, looking at the properties of MyModel, there are:
entity container name, filled with ‘MyEntities’. So the connection string name goes here.
namespace, filled with ‘MyModel’. This is coming from the table selection textbox.
Putting something into the edmx custom tool namespace doesn’t seem to do anything. I got this conclusion because when I grep the entire source code folders, I found it only in a vbproj file.
Putting ‘TheModel’ into MyEF.tt custom tool namespace produces error from MyEF.Context.vb saying type ‘MyTable’ (this is the name of my database table) is not defined.
Can someone explain the purpose of each label?
If I want to put all the classes generated by this one edmx (DbContext, models, etc.) into one namespace, ‘MyEF’, what should I put in each of those places?
The various properties are used as follows:
EDMX file name --> Used for the EDMX file name
Connection string name --> Used for the connection string name in the config file, and also for the container name of the conceptual model (CSDL) part of the EDMX
Model namespace --> Used for the namespace of the conceptual model (CSDL) part of the EDMX, and also for the store model (SSDL) part with .Store appended
Custom tool namespace for the EDMX file --> I don't believe this is used for anything when using T4 generation of POCO entities. When using EF1-style built in code generation, setting this property will set the .NET namespace for all generated files.
Custom tool namespace for .Context.tt file --> The .NET namespace used in the source file for the context
Custom tool namespace for .tt file --> The .NET namespace used in the source files for the entities
Note that if you set the .Context.tt and .tt custom namespaces to different things, then the context will be generated in a different namespace to the entity types and this won't compile out-of-the-box. You can update the .tt files if you want to use different namespaces here, but more often people just use the same namespace for both.
Also note that you may need to choose "Run Custom Tool" from the context menu for each .tt file after changing the properties in order for the code to be re-generated.
Related
I just upgraded to EF6 from EF5 and I encounter this error in a custom T4 that connects to the DB using a DbContext from a different assembly.
File: EF6.Utility.CS.ttinclude
Compiling transformation: The name 'ArgumentNotNull' does not exist in the current context
What I've done is replacing EF.Utility.CS.ttinclude with EF6.Utility.CS.ttinclude, which solved another error about DbSet and DbContext not being found.
The T4 is very simple, like this one:
using(var context = new EntityContext)
return context.Entities.Where(x => 1==1);
Except for the EF include I only reference my own assemblies. The freshly-added Context is generating just fine (in another project).
What on earth could be wrong?
EF6.Utility.CS.ttinclude reference some static functions that are defined in the main template.tt so you need to have them in your template too.
Example:
Entity.tt defines ArgumentNotNull(T arg, string name) which is used in the EF6.Utility.CS.ttinclude (it's not the way we are used to have)
See the bottom of generated template from EF6 designer to see this missing functions
One way to solve this is moving almost all the code to a .cs file and then use that file in the T4 template. Then remove the EF ttinclude from the T4 template.
Works and is easy better praxis to follow.
Background
Visual Studio 2012
NEW Model.EDMX file created in VS2012
Copied some of the EDMX xml from a previously created EDMX into the new one
Problem / Question
Now. The EDMX (TT transform, custom tool, whatever, etc.) is generating BOTH DbContext classes (under the Model.tt/Model.Context.tt files) and ObjectContext classes (via the Model.designer.cs file). See image below:
Everything builds fine and works with the DbContext (but obviously only if I delete the Designer.cs file just before building) but the Designer.cs - and its ObjectContext-based code - keeps reappearing. How do I stop this behavior?!
I didn't find out how to stop the Designer.cs file from generating the ObjectContext, but I did figure out how to make it so that it doesn't matter. Just set the Build Action to "None" instead of "Compile".
The .tt files will generate the code regardless of the code generation strategy in the .edmx. They listen to the .edmx file changes. At least this is how they are working for me.
So by turning the code generation strategy to None in the .edmx you make the .designer.cs file empty of any useful content.
Then open up the project file, find the nodes representing the .edmx, by default it is contained in EntityDeploy node ie the Build Action value, and remove its Generator subkey.
On normal EF Code First projects, Code Generation Strategy is "None" and ObjectContext is not generated.
It appears in your case that you Code Generation Strategy set to "Default".
To stop generating ObjectContext in xxxx.Designer.cs, go to your edmx file, and change your Code Generation Strategy from "Default" to "None".
If you inspect xxxx.Designer.cs
// Default code generation is disabled for model 'C:\Users\xyxy\xyxyxy.Web\Models\xyxy.edmx'.
// To enable default code generation, change the value of the 'Code Generation Strategy' designer
// property to an alternate value. This property is available in the Properties Window when the model is
// open in the designer.
I think the issue is having an EntityModelCodeGenerator value in the Custom Tool field of the .edmx file properties. Just delete that value.
I think this is it, because I notice that in the project that I started off as an EF6 project, there is no value and it has no .designer.cs file, but in the two that I upgraded from EF4, they both have the value and the designer file.
(This equates to a <Generator> tag in the underlying .csproj file.)
In VS 2010 and EF 4.4, you were able to move and edit .tt files when using the DBContext generator in Entity Framework such that your POCO objects where in a different project than your DBContext files.
See Here and Here for examples of what I am talking about.
In VS2012 / EF5 this seems not to be possible. the POCO classes are generated as a subitem under the EDMX file. The files cannot be copied from within Visual Studio. Moving the files from Explorer does not help because the files you moved get recreated at compilation time.
Am I missing something basic here?
I am not using any code generation items with EF5 (whereas I was with EF4.x.) Could that be the difference?
In Visual Studio 2012, when you add an ADO.NET Entity Data Model (*.edmx), it includes the T4 templates for the context and model classes as sub-items of the EDMX file. For example, if you add MyModel.edmx, it will have 4 sub-items as follows:
MyModel.Context.tt
MyModel.Designer.cs (in C# projects)
MyModel.edmx.diagram
MyModel.tt
MyModel.tt generates the POCO entities as sub-items. To generate the entities in a separate project, follow the following steps:
Create a separate class project.
Add new item, choose the "EF 5.x DbContext Generator" template. This creates the *.tt file. For example MyModel.tt.
Edit the template file as follows:
const string inputFile = #"MyModel.edmx"; // old value (remove)
const string inputFile = #"..\MyOtherProjectName\MyModel.edmx"; // new value
In your other project, expand the EDMX file and right-click on MyModel.tt, select Delete.
That's it. You're done. You now have your model and context in one project and the entities in a separate project.
Check out the following post: Visual Studio 2012 - Can't move EF .tt files
It speaks to how you can remove the dependency information of the .tt file to the .edmx file within the assoicated .csproj file. This will then allow you to drag the .tt file from within Solution Explorer.
Just make sure to update the file path in the begining of the .tt file to point to the .edmx as described in the previous answer and shown below:
const string inputFile = #"..\EFTest\EFTestModel.edmx";
There are actual several pieces and steps and missing any single one can prevent the separation of the POCO classes from working correctly. I created a blog post that details the entire process that you can view below:
Separating Entity Framework POCO Classes Generated From T4 Template in VS.NET 2012:
http://allen-conway-dotnet.blogspot.com/2013/01/separating-entity-framework-poco.html
So, you DO have to move it through windows Explorer now. And then edit the path to the EDMX file in the .tt file you moved. Once you do that it works. (I know I say it does not above, but I must have done something wrong the first time I tried.)
As my database was designed using german table- and column names, the default pluralisation feature of entity framework doesn't work for me.
I have found a couple of resources where this is discussed, but none of them seem to work.
What i have found:
There is the PluralisationService where i can add the mappings:
PluralizationService pluralizer =
PluralizationService.CreateService(CultureInfo.GetCultureInfo("en-us"));
ICustomPluralizationMapping mapping = ps as ICustomPluralizationMapping;
mapping.AddWord("Tabelle", "Tabellen");
But what's next?
I have tried to:
EntityModelSchemaGenerator generator = new EntityModelSchemaGenerator(container);
generator.PluralizationService = pluralizer;
generator.GenerateMetadata();
and put both of them in my POCO T4 Template. But it throwed the following exception:
The EntityContainer 'ContainerName' is not a store EntityContainer. Parameter name: storeEntityContainer
at System.Data.Entity.Design.EntityModelSchemaGenerator.Initialize(...)
at Microsoft.VisualStudio.TextTemplating...GeneratedTextTransformation.TransformText()
To completely customize the table names in EF Code First, you can use the Table attribute to explicitly specify the name of the table associated with a class:
[Table("InternalBlogs")]
public class Blog
{
//...
}
I'm also looking for the same thing. Maybe this can help. I'm just not willing to pay for such a basic feature.
EDIT:
The code you posted is to be used with EdmGen2 wich will give you CSDL, SSDL or MSL files pluralized according to your class.
A very old question, but if someone is still looking for a possible workflow/solution:
I had a similar problem where I wanted to customize the schema import (CSDL) from the database. The solution / workflow was as follows:
Deployed the database schema (I used Visual Studio Database Project VS 201x) to a
local database
Imported the database model using EDMGEN to create the CSDL, SSDL and MSDL files
http://msdn.microsoft.com/en-us/library/vstudio/bb387165(v=vs.110).aspx
Modified EDMGEN2 with my changes on how to handle pluralization and naming with custom rules and created EDMX file
Ran the T4 templates (with additional customization as needed) to create
output.
I'm trying to run codeanalysis on an assembly that contains an entity model (edmx file). In project properties I have checked the "Suppress results from generated code" option, but I am still getting a lot of CA errors pertaining to the auto-generated EF code.
Has anyone experienced this? And is there a work-around?
Just put the attribute on your class definition.
But how to do it, since your file can get overridden any time. Use a separate file, since all generated classes are partial classes. Open a separate file, and write something like:
[GeneratedCode("EntityModelCodeGenerator", "4.0.0.0")]
public partial class YourEntitiesContextName : ObjectContext
{
}
This will skip code analysis on your particular generated class. StyleCop for instance is more smart and doesn't touch files that have .designer/.generated part in their name or regions that have generated word in their name.
Well, "Suppress results from generated code" really means "Don't look at types with GeneratedCodeAttribute". EF's code generator hasn't added this, historically (though I've suggested it to the team). But you can add it if you use custom T4.