43

I'm trying to use the Repository Pattern with EF4 using VS2010.

To this end I am using POCO code generation by right clicking on the entity model designer and clicking Add code generation item. I then select the POCO template and get my classes.

What I would like to be able to do is have my solution structured into separate projects for Entity (POCO) classes and another project for the entity model and repository code.

This means that my MVC project could use the POCO classes for strongly typed views etc and not have to know about the repository or have to have a reference to it.

To plug it all together I will have another separate project with interfaces and use IoC.

Sounds good in my head I just don't know how to generate the classes into their own project! I can copy them and then change the namespaces on them but I wanted to avoid manual work whenever I change the schema in the db and want to update my model.

Thanks

Max
  • 1,543
  • 2
  • 16
  • 31

3 Answers3

38

Actually the T4 templates in EF 4.0 were designed with this scenario in mind :)

There are 2 templates:

  • One for the Entities themselves (i.e. ModelName.tt)
  • One for the ObjectContext (i.e. ModelName.Context.tt)

You should put the ModelName.tt file in you POCO project, and just change the template to point to the EDMX file in the persistence aware project.

Sounds weird I know: There is now a dependency, but it is at T4 generation time, not at compile time! And that should be okay? Because the resulting POCO assembly is still completely persistence ignorant.

See steps 5 & 6 of this: http://blogs.msdn.com/adonet/pages/walkthrough-poco-template-for-the-entity-framework.aspx for more.

Hope this helps

Alex

Alex James
  • 20,874
  • 3
  • 50
  • 49
  • Link to msdn blog page not found – Amr Elgarhy Sep 19 '16 at 21:34
  • @AmrElgarhy Internet Archive to the rescue! Checkout [http://web.archive.org/web/20110609064124/http://blogs.msdn.com/b/adonet/archive/2010/01/25/walkthrough-poco-template-for-the-entity-framework.aspx](http://web.archive.org/web/20110609064124/http://blogs.msdn.com/b/adonet/archive/2010/01/25/walkthrough-poco-template-for-the-entity-framework.aspx) – natenho Oct 12 '16 at 14:58
  • You sir are a legend! :D –  Nov 23 '17 at 03:20
6

@Nick,

  1. To force the regeneration of the POCO entities, you just need to right-click the main .tt file and select "Run Custom Tool". This will force it to regenerate your POCO classes with your updated changes to the .edmx model.
  2. Is there any problem with you going ahead and Right-clicking the model and selecting "Generate Database from Model..." even though you aren't necessarily generating the database? That will most likely get rid of your 'Error 11007...'.
  3. I think it's equivalent to a "Code Behind". I don't know any more than that.

One other thing to note about the link that Alex gave. Once I moved my main .tt file to a different project, the file that was generated from the ".Context.tt" file would not compile because it was missing references to the POCO files that were located in a different namespace (because I wanted my ObjectContext to be in a different domain than my POCO files). I had to modify the ".Context.tt" file to had a using Poco.Namespace (where Poco.Namespace is the name of the namespace where the POCO files were generated). This then allowed my project to compile.

Joel

goodman
  • 547
  • 6
  • 12
  • re: 2.When compiling I now get this warning for each entity: 'Error 11007: Entity type XXXX is not mapped.'. This may relate to not having generated the database (?) but this was not happening previous to the move I edited the edmx (using an xml editor) to remove the mapping that was there (even though it looked perfect to me), then went back to the designer and added the mapping using the tool. –  Apr 04 '11 at 19:44
  • I had this *exact* same issue with the ".Context.tt" file and wanted to add a `using` statement which did work. Problem is that file is auto generated. If the model has to be updated, the `using` statement will have to be deleted and re-added. Any better way to fix this? – atconway Jan 04 '13 at 20:11
  • Never mind, just figured this out after looking at the link from Alex. Scroll to the section named **7. Change “Blogging.Context.tt” namespaces to match “Entities”** The **Custom Tool Namespace** on the Context.tt properties can be updated to say `MyProject.Model` and the references will resolve. – atconway Jan 04 '13 at 20:15
3

For EF5 + DbContext generator: It's easy to move your Name.Context.tt to a different project. However, you will need to reference the model classes. You can do this manually, but this will require you to change it every time code gets generated. You could also use the same namespace for both projects. This is valid and will work, but I think this is bad design. Another alternative is to change the T4 template (Name.Context.tt).

Change this (line 43):

using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
<#
if (container.FunctionImports.Any())
{
#>

To this:

using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
<#
if (modelNamespace != codeNamespace)
#>
using <#=code.EscapeNamespace(modelNamespace)#>;
<#
if (container.FunctionImports.Any())
{
#>

This will check if your model namespace differs from your code namespace, if so, it will insert the required using to reference your model classes.

J.G. Hek
  • 31
  • 1
  • _"...but this will require you to change it every time code gets generated..."_ - if you mean _when the TT file gets regenerated by the EDMX or something_ then I usually have the TT in source control ahead of time and simply revert changes –  May 07 '19 at 08:06