Entity Framework generated classes are not in the namespace I require, is there a way of changing the namespace it uses without regenerating? - entity-framework

If I need to regenerate where should the namespace be specified. I am trying to use partial classes from within the Models namespace however they don't match.
The simplified code fragment below is where the entity framework classes have been generated
namespace projectname
{
#region Contexts
/// <summary>
/// No Metadata Documentation available.
/// </summary>
public partial class MyClass
{
}
}
When I add a class to my models folder,
namespace projectname.Models
{
public partial class MyClass
{
//etc, etc
}
}
As you can see the namespaces don't match causing issues when I try and use them as the compiler is seeing both projectname.Models.MyClass and projectname.MyClass.
I would like some advice on the correct way to fix this, preferably to update the E.F. classes so they exist in the projectname.Models namespace, but I am not sure how to go about it.

In line with Roman O's comment, namespace can be changed by updating "Custom Tool Namespace" property of text transform (.tt) file, which ties generated entity classes (in Database First approach) to entity model (.edmx) file. This works in VS 2012 Express with EF 5.0.
I would post a screenshot but for lack of reputation.

IIRC, if you are using an Entity data model, you should be able to change the namespace directly through the xml file or files (you may have to change it for all the various storage and and conceptual models). There might even be some way to change it in the designer.. seems simple enough.
Actually, the solution might be here:
Generated Code Overview (Entity Data Model Designer) (see Custom Tool Namespace)

Right click the .edmx file in the project in Solution Explorer and select Properties
In the VS properties pane, fine Custom Tool Namespace
Enter the full CLR namespace you'd like
Rebuild the project

Namespace of auto-generated classes will be inherited from VS project settings (and even change if you change it there). Of course you should have "Custom Tool Namespace" property empty. (just tested it with VS2013 and EF6.1)
Unlike settings files which had always been pita :)
For older version there is a good video on manual changing :
https://youtu.be/B7Cqc9F0Ih8

Related

EntityFramework: how to modify edmx to change format of entity names and properties

I am using the Entity Framework to generate data access code from an old database.
The database table names and properties are all named in capitals with _ to separate words ie. CLIENT, CLIENT_NAME, D_CLIENT_ID etc.
I have written a class to transform these into camel cased strings:
public static class Extensions{
public static string FirstCharToUpper(this string input)
{
return input.First().ToString().ToUpper() + input.Substring(1).ToLower();
}
public static string CamelCase(this string input)
{
return input.Split('_').Where(a=>!string.IsNullOrEmpty(a)).Select(a=>a.FirstCharToUpper()).Aggregate((a,b)=>a+b);
}
}
I am invoking this from my tt files and I have got to the point where my data classes and DbContext naming is the way I want it.
However I now get an error when I try to create a controller: 'Unable to retrieve metadata for myNamespace.Client'. Could not find the CLR type for 'myModel.ENTITYNAME'. (in capital)
To fix this, I made my Data.tt decorate my data classes with [Table("ENTITYNAME")] and my properties with [Column("COLUMNNAME")] - however this did not make any difference.
What am I missing?
Are you updating it the same way in all three (or two corresponding) layers: CSDL/MSL/SSDL? I would suspect there is a mismatch between two of the layers.
Possible useful in this case - here is a library I wrote for creating/updating/manipulating EDMX files a bunch of years ago: https://github.com/KristoferA/HuagatiEDMXTools/
If you use an older version of Visual Studio (2013 or older) then I also have a free VS addon/plugin that adds renaming and db<->model sync etc. You can download it from here:
https://huagati.com/edmxtools/
Update: based on the comments below, I think you are renaming classes and properties in the generated code without making the corresponding change in the CSDL.
Instead of changing the generated code / tt templates: change the names in the CSDL and the references to those CSDL objects in the MSL. Then the default templates will generate code with the class/property/etc names you want.

Creating global aspects in postsharp

I am looking for a way in which to all aspects to run on methods in many places in my project, without having to manually add in the attribute tag to each method or class.
My entire solution holds around 20 separate projects. One of which I have created called myname.space.Attributes which holds my attribute declarations, as well as a file called GlobalAspects which has the following:
using PostSharp.Patterns.Diagnostics;
using PostSharp.Extensibility;
using myname.space.Attributes;
// This file contains registration of aspects that are applied to several classes of this project.
[assembly: TraceLoggingAttribute(AttributeTargetTypes = "myname.space.Controllers.*",
AttributeTargetTypeAttributes = MulticastAttributes.AnyVisibility,
AttributeTargetMemberAttributes = MulticastAttributes.AnyVisibility)
]
[assembly: TraceLoggingAttribute(AttributeTargetTypes = "myname.space.Repositories.*",
AttributeTargetTypeAttributes = MulticastAttributes.AnyVisibility,
AttributeTargetMemberAttributes = MulticastAttributes.AnyVisibility)
]
The goal of this was to add my TraceLoggingAttribute to all the methods held within these other 2 projects, Controllers and Repositories.
I have set up these 2 other projects to reference the Attributes project, and the attribute works perfectly fine if I put the [TraceLoggingAttribute] tag on the classes and methods within the Controller and Repositories projects.
Is there a way in which I can set up my GlobalAspects.cs to work in the way I am looking for? Please ask question if I have not explained the issue well enough here
For interest, the TraceLoggingAttribute is defined as:
namespace myname.space.Attributes
{
[MulticastAttributeUsage(MulticastTargets.Method, TargetMemberAttributes = MulticastAttributes.Instance)]
[Serializable]
public class TraceLoggingAttribute : OnMethodBoundaryAspect
{
Unfortunately you can only apply attributes to currently compiled assembly (or to calls to other assemblies through TargetAssembly property but that also affects only currently compiled assembly).
I think that the easiest solution would be to link GlobalAspects.cs into all projects that you want to be affected by it. This should work as you expect and not cause any problems.
Hope that helps.

Entity Framework 5 model first - Where is IDisposable gone?

In Entity Framework 5 model first, there seem to be some breaking changes due to the way the class files are generated (No more code generation, but T4 templates)
2 examples:
The generated context file doesn't implement IDisposable anymore
There isn't a constructor which takes a connectionstring anymore
Are there more breaking changes? And what is the solution to them?
The default code generated from a model in Entity Framework 5 now inherits DbContext instead of ObjectContext.
This still implements IDisposable, but if you're getting an error from a line of code similar to this:
using (var mymodel = new MyModelContext()) { ... }
...complaining about not implementing IDisposable, then your problem is most likely that your model is defined in a separate assembly that references EF5 and you have not added an EF5 reference to your project.
As Ladislav Mrnka has already mentioned in his answer, if you want to pass a connection string to the constructor you have to create your own constructor manually to do this.
If you want to switch Entity Framework back to the older style of generated code, which will automatically generate the constructor you're looking for, then follow these steps:
Click on the designer surface of your EDMX file, and look at the properties window. Find a property called "Code Generation Strategy" and set this to "Default" instead of "None". This will tell Visual Studio to start creating the code for your object model in MyModel.Designer.cs in one big file, this time using ObjectContext instead of DbContext.
Delete the following sub files from below your EDMX file: MyModel.Context.tt, MyModel.tt. These are the auto generated files that you don't want anymore. If you don't delete them you'll get class naming conflicts because your objects will be created twice.
The generated context file doesn't implement IDisposable anymore
IDisposable is still implemented by the parent context type. The generated type is still disposable.
There isn't a constructor which takes a connectionstring anymore
It now uses convention to get connection string but you can add your own constructor either to template or to your partial class part of the context.
Are there more breaking changes? And what is the solution to them?
It is whole breaking change because it uses different API - DbContext API instead of ObjectContext API which means different types, different methods, POCO entities etc. If you want to get back to original code generation you have to delete those T4 templates and enable code generation as described in .Designer.cs file but the current recommended way is to use POCOs and DbContext API.
I was having the same issue with the using statement needing a type that extended IDisposable... Turns out that I forgot to reference System.Data.Entity in my project... Added the reference and it fixed the problem.
Just clean and build the project, don't forget to add the reference to your entity.

How to implement IDbContextFactory for use with Entity Framework data migrations

I am trying to use Entity Framework data migrations, as described in this post.
However, when I try to execute the Enable-Migrations step, I receive the following error in Package Manager Console:
The target context 'MyDataContext' is not constructible. Add a default constructor or provide an implementation of IDbContextFactory
So, I created a factory class that implements IDbContextFactory in the project that contains my DbContext class, but data migrations doesn't appear to recognize it.
Is there something that I should explicitly do to instruct data migrations to use this factory class?
I also hit this problem as i wrote my context to take a connection string name (and then used ninject to provide it).
The process you've gone through seems correct, here is a snippet of my class implementation if it's of any help:
public class MigrationsContextFactory : IDbContextFactory<MyContext>
{
public MyContext Create()
{
return new MyDBContext("connectionStringName");
}
}
That should be all you need.
Like #Soren pointed out, instead of using IDbContextFactory, not supported on some earlier EF Core releases (i.e. EF Core 2.1), we can implement IDesignTimeDbContextFactory<TContext>, which supports the missing ConnectionString parameter.
For a settings.json based aproach, which you can use with either of the referred interfaces, check #Arayn's sample which allows us to define "ConnectionStrings:DefaultConnection" value path
Update 1
According to #PaulWaldman's comment, on EF Core 5 support for IDbContextFactory was reintroduced. For further details, check his comment below.

Entity Framework 4.0 Autogenerated Classes not marked as Serializable

One strange thing i've got to see in Entity Framework 4.0 V2 Auto Generated Classes(tt) is that the classes are not marked as Serializable. Although they are having DataContract attribute for WCF.
Now the problem is, when I store the POCO object into viewstate it throws me an exception saying that the class is not serializable.
If I generate the classes without the t4 templates or using the defualt class generating scheme, what i see is that the generated classes are having the Serializable attribute on them.
But unfortunately i can not make use of the default Entity Generation Scheme. Since I want to accomodate some custom logic to the autogenerated class which is possible through t4 templates only.
Now what i want to know is:
1) Why the Serializable Attribute is not there in the autogenerated class or am I making any mistake or i am towards a wrong approach.
2) Is it a good idea to customize the EF 4.0 T4 template to accomodate Serializable attribute.
Looking for your valuable suggestion.
Thanks,
Burhan Ghee
Yes you can modify the template. Look at Adding [DataMember] [DataContract] attributes in Entity Framework POCO Template for exactly what you need to do to fix your template. Look specifically at the WriteHeader function in the template.
The purpose of T4 template is allow you to customize. Customize it fearlessly! You are not only encouraged to customize template, but also the edmx file that your template is based on.
see this http://blogs.msdn.com/adonet/archive/2010/03/05/updated-data-model-designer-extension-starter-kit.aspx