EF 4.0 to EF 4.2 , DeleteObject Not Found, - entity-framework-4

My original project is in Asp.net MVC 2.
I convert my project to MVC 3 without problem.
In the same time, I install the EntityFramework 4.2. Again without problem.
Were it's begin to be complicated is when I add the T4 Generate DBContext.
Thats create me the T4 properly and generate all my entity into his own "POCO Class". Thats perfect!.
When I Build my project, I Got about 400 error. Here is some example.
'mvn.Models.DBEntities' does not contain a definition for
'AddToLeaseConditionInfos' and no extension method
'AddToLeaseConditionInfos' accepting a first argument of type
'mvn.Models.DBEntities' could be found (are you missing a using
directive or an assembly reference?)
As you can see here, the context.AddToLeaseConditionInfos(objCondition); doesn't work anymore.
Same for the DeleteObject context method.
context.ConvertionUnits.DeleteObject(MyObjConvertionUnit);
Someone has an Idea.
Thanks a lot.

You previously used ObjectContext API and default code generator (or EntityObject T4 template) but now you are trying to use DbContext API with POCO DbContext T4 Generator. Those two are completely incompatible because they represent different API. You must use the same code generation approach as you used in EFv4 (which means upgrade will not give you almost any additional value) or you must rewrite your current data access code to use new API.

Related

Issue registering generic types with Autofac in ASP.NET Core

I'm a relatively new user of both Autofac and ASP.NET Core. I've recently ported a small project from a 'classic' ASP.NET WebAPI project to ASP.NET Core. I am having trouble with Autofac, specifically in registration of generic types.
This project uses a Command pattern, each command handler is a closed generic like
public class UpdateCustomerCommandHandler: ICommandHandler<UpdateCustomerCommand>
These command handlers are injected into the controllers like:
readonly private ICommandHandler<UpdateCustomerCommand> _updateCustomerCommand;
public ValuesController(ICommandHandler<UpdateCustomerCommand> updateCustomerCommand)
{
_updateCustomerCommand = updateCustomerCommand;
}
Autofac is configured (partially) as:
var builder = new ContainerBuilder();
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
//This doesn't seem to be working as expected.
builder.RegisterAssemblyTypes(assemblies)
.As(t => t.GetInterfaces()
.Where(a => a.IsClosedTypeOf(typeof(ICommandHandler<>)))
.Select(a => new KeyedService("commandHandler", a)));
The above does not seem to be registering the generic as expected. If I use the below method for registration, it works well.
builder.RegisterType<UpdateCustomerCommandHandler>().As<ICommandHandler<UpdateCustomerCommand>>();
When I say "It doesn't work", what I mean is that when attempting to instantiate the controller, I get "InvalidOperationException: Unable to resolve service for type 'BusinessLogic.ICommandHandler`1[BusinessLogic.UpdateCustomerCommand]' while attempting to activate 'AutoFac_Test.Controllers.ValuesController'."
This worked well in the Full WebAPI version of this project, but not after recreating it in ASP.NET Core. To be clear, this was working perfectly well before porting to ASP.NET Core.
Here is a link to the code that I've used to recreate this issue:
https://dl.dropboxusercontent.com/u/185950/AutoFac_Test.zip
**** EDIT AFTER SOLUTION DISCOVERED ****
There was nothing in fact wrong with my Autofac configuration and certainly not Autofac itself. What had happened was that I had renamed the output of my dependent assemblies in an effort to make the assembly scanning stuff (replacing of AppDomain.CurrentDomain.GetAssemblies() more elegant, however I never modified the dependencies of the API project to reference the new assemblies. So Autofac was scanning the correctly loaded assemblies which happened to be the older versions, which did not contain the interfaces and implementations I expected...
Autofac has built-in support to register closed types of open-generic.
builder
.RegisterAssemblyTypes(ThisAssembly)
.AsClosedTypesOf(typeof(ICommandHandler<>));
This will scan your assembly, find types that close the open generic ICommandHandler<> interface, and register each of them against the closed generic interface they implement - in your case, ICommandHandler<UpdateCustomerCommand>.
What doesn't work in your example is that you associate a key to your services. Autofac doesn't look for the keyed version of your ICommandHandler<UpdateCustomerCommand> when trying to instantiate the ValuesController, which is why you get the exception.
Edit after QuietSeditionist's comment:
I'll try to elaborate a bit on the keyed vs. default services. The way you registered your handlers is by associating the commandHandler key to them.
This means that once the container is built, here's the only way you can resolve such a handler:
// container will look for a registration for ICommandHandler<UpdateCustomerCommand> associated with the "commandHandler" key
container.ResolveKeyed<ICommandHandler<UpdateCustomerCommand>>("commandHandler");
When instantiating ValuesController, Autofac doesn't look for a keyed registration of ICommandHandler<UpdateCustomerCommand>, because it wasn't asked to.
The equivalent code it's executing is - and you can try to run that code yourself to get the exception:
// BOOM!
container.Resolve<ICommandHandler<UpdateCustomerCommand>>();
The reason your second registration works is because you didn't key the service:
// No key
builder
.RegisterType<UpdateCustomerCommandHandler>()
.As<ICommandHandler<UpdateCustomerCommand>>();
// commandHandler key
builder
.RegisterType<UpdateCustomerCommandHandler>()
.Keyed<ICommandHandler<UpdateCustomerCommand>>("commandHandler");
But since you don't want to register all your handlers one by one, here's how to register them without keying them:
builder
.RegisterAssemblyTypes(ThisAssembly)
.AsClosedTypesOf(typeof(ICommandHandler<>));
/Edit
I can see two scenarios where keying services can be useful:
You have several types implementing the same interface and you want to inject different implementations in different services. Let's say, you register both SqlConnection and DB2Connection as IDbConnection. You then have 2 services, one which is supposed to target SQL Server, the other one DB2. If they both depend on IDbConnection, you want to make sure you inject the correct one in each service.
If you use decorators, the way registrations work is you define the services to which the decorators will apply by a key - the first example is self-explanatory
Because Google brings you to this page even when you're trying to manually register types, I thought that even though this doesn't answer the asked question, it would be useful for future visitors. So, if you want to manually register a generic type, you would use this format:
service.AddTransient(typeof(IThing<>), typeof(GenericThing<>));
or if there's no interface, then just:
service.AddTransient(typeof(GenericThing<>));
and for completeness, if you have a generic with multiple types:
services.AddTransient(typeof(GenericThing<,>));

Razor Engine not working in ASP.net 5 MVC 6

I am trying to migrate some existing code from MVC5 to MVC6 and I am having difficulty with this particular code:
Engine.Razor.RunCompile(File.ReadAllText(emailTemplatePath), "emailTemplateKey", typeof (EmailViewModel), emailViewModel);
I am receiving the following runtime error:
MissingMethodException: Method not found: "Void Microsoft.AspNet.Razor.CodeGenerators.GeneratedClassContext.set_ResolveUrlMethodName(System.String)". in RazorEngine.Compilation.CompilerServiceBase.CreateHost(Type templateType, Type modelType, String className)
The original code I was using in MVC5 was taken from here. If there is no way of converting the above code to work with MVC6 what is another elegant way of doing email templates?
Apparently there has been a change in GeneratedClassContext class - the property ResolveUrlMethodName does not exist anymore, hence the MissingMethodException. Looks like ParserContext class has changed too, since accessing OnError event handler throws the same exception.
In fact it is the setter of the missing property missing (pardon the expression!), which, being a method, causes the exception. Absolutely accurate but somewhat misleading, unless you recall this.
Quite a similar question (and a good answer with alternative solution!) here: RazorEngine and MVC 6 beta 7.

XmlMediaTypeFormatter cannot write an object of type ObjectQuery

When using EntityFramework and returning an IQueryable from an MVC 4 Web API Get action, the following error occurs when the XML serializer is set to use the old XmlSerializer (rather than DataContractSerializer).
XmlMediaTypeFormatter cannot write an object of type ObjectQuery
Is this a known issue?
Too late for this question but for those who faced the same exception:
Your ObjectQuery class probably lacks a default constructor.
See my full answer here: Xml Serialization cannot write an object of type 'x'
No.
You need to define [Queryable] attribute on your action. This requirement was added on RC and probably will be removed at RTM
NOTE
OData support is very unclear at the moment. I have created PocoHttp for consuming ASP.NET Web API's OData but paused development because of lack of clarity at the moment.
I had this error because one of the members of the class I was serialising was an interface. I didn't need to serialise that member so annotating it with a [XmlIgnore] attribute fixed it.

Error generating <DbContext>

I am trying stuff out on MVC4 Beta. Project is in VS11, EF 5.0-Beta, using Code First approach.
Created simple Model poco and DbContext derived class with single IDbSet<> property for model class. Connection string with LocalDb.
I noticed when context's Entity Set property is type of IDbSet<> then I get message from VS when I try to create new controller with “Controller with read/write actions and views, using Entity Framework” Scaffolding template:
"There was an error generating 'MyProject.MyNamespace.MyContext'. Try rebuilding your project."
Even Clean Solution and building again doesn’t help.
If I changed Entity Set property to type DbSet<> then controller scaffolding succeeds.
Is it a bug or is it expectable?
Br,
Lauri
It is not a bug you cant instantiate an instance of an Interface. The I in front of IDbSet denotes the type as an interface (By convention). So you were trying to create an instance of that interface. Instead you need to delcare it with DBSet<> which is an implementation of the IDBSet<> interface. I hope this clarifies your issue.

Ninject 2.2 multiple bindings

I recently updated ASP.NET MVC 3 app to Ninject 2.2.
Previously I had the following interface to implementation binding in my main app:
Bind(typeof(IMyInterface<>)).To(typeof(MyImplementation<>)).InRequestScope();
In addition, I had the following in a different assembly that was being loaded by my main app:
var arg = new ConstructorArgument("info", "something");
Bind<IMyInterface<MyClass>>().To<MyImplementation<BlogComment>>().WithParameter(arg);
This worked fine previously and the more specific implementation (the one with the argument) was being recognized. However, when I upgraded to Ninject 2.2, I received the following error:
Error activating IMyInterface{MyClass}
More than one matching bindings are available.
Activation path:
2) Injection of dependency IMyInterface{MyClass} into parameter myParam of constructor of type SomeOtherClass
1) Request for IMyInterface
Suggestions:
1) Ensure that you have defined a binding for IMyInterface{MyClass} only once.
What change was made from 2.0 to 2.2 that is causing this and is there a work around?
Ninject 2.2 ensures that only one matching bindings exists when resolving instances. 2.0 returned an instance of the first matching binding ignoring that there are others. But having multiple bindings if only one is requested reflects a bad configuration and can lead to hard to detect unintended behaviors.
But I see that there should be the possibility to overrule open generic bindings with more specific ones. I'll definitely look into it and it will either be added to a bugfix release or the next major release.

Resources