Argument Exception - entity-framework

Exception:
The specified named connection is either not found in the configuration, not intended to be used with the EntityClient provider, or not valid.
Method where exception happened:
/// <summary>
/// Initializes a new DSAplcEntities object using the connection string found in the 'DSAplcEntities' section of the application configuration file.
/// </summary>
public DSAplcEntities() : base("name=DSAplcEntities", "DSAplcEntities")
{
this.ContextOptions.LazyLoadingEnabled = true;
OnContextCreated();
}
What exactly does this exception mean and how can I fix it?

Found the solution. The problem was that I was using WCF Services in my project and I did not copy the connection string to the App.Config inside the service solution.

The string arguments passed to the base class constructor are used to pass in either a named connection string (defined externally in a config file) or the connection string itself, depending on which constructor is invoked.
It looks like you're invoking the constructor on ObjectContext that takes two arguments, the first of which must be a valid connection string. The string you are passing in is not a valid EF connection string, which is why you get the error message from EF.
Check if you have the actual connection string defined in your config file. Note what name it has been defined with and pass in that name as the first argument (and if that doesn't work, try removing the second argument - I'm not sure if the method you're calling accepts a named connection string).

Related

Where does Entity Framework code-first migration deploy database

I have a library for the data access layer where it uses Entity Framework, in the DbContext class I pass the connection string name DefaultConnection through the constructor, then I add this connection string to the app.config file for this library.
But when I update to the database I find the database is not created into this connection string server and catalogue?
Anybody please explain how migration and update database handle connection strings?
Your library can't access the app.config file in run time. Only executable components can (a web api, a console application, etc.). You have to define the connectionString value in the config file of the executable component that uses your library, not in the library's app.config file. The only scenario when the library's app.config file connection string can be used is when running Entity Framework commands in the Package Manager console (like add-migration and similar ones).
The recommended way to deal with connection strings is that the data layer library doesn't care at all about the responsibility of obtaining the connection string value. Instead, the client that uses the library should provide the connection string when instantiating the data layer classes. The responsibility of getting the value should be in that client component, using code like this to get the value to be passed to the data layer:
var connectionString = Configuration.GetConnectionString("MyConnectionString");
A common practice is to use a dependency injection component (like Autofac) so that the client injects the connection string as a parameter in the DbContext constructor, or in a property, after getting it from the configuration file (or possibly from other place).
There are also several approaches about what parts of your data layer you expose to the client components that use it: you can directly create instances of the DbContext, or use the Repository pattern, or the UnitOfWork pattern. The important concept here is that whenever your client component creates an instance of one of your data layer classes, it has to get the connection string value from wherever it is and pass it to the data layer component (via directly invoking the constructor and passing the connection string value as a parameter, or setting a property, or via your dependency injection component).
More info here and here.
Update: added some info about execution from Package Manager console:
To pass the connection string tothe Package Manager console you can do several things:
Add an explicit parameter ConnectionString to your console commands (the complete connection string, not only the name in the config file). This avoids the need to add the connection string to your library's config file.
Add an explicit parameter ConnectionStringName to your console commands. Define that connection string in the library app.config (but be careful and don't forget that it will only be used from the console, and that the one used in run time is the one in the executable component config file. This approach may lead to some mistakes).
Add a parameterless constructor to your DbContext with the connection string name hard-coded in the base constructor call, like this:
public MyDbContext() : base("DefaultConnection") { ... }
This will be the one that console manager will use. For real code execution use the other constructor with the parameter. Again, the connection string must be defined in the library's app.config file and this may lead to mistakes.
Also, console manager uses by default the configuration from the project selected as start project in your solution. If this project is not the database library it will not work like you want. To fix this you should set your solution as "Multiple start up projects", and select the database layer project in the console manager "Default project" drop down list (or pass a DefaultProject parameter with the data layer project name to your console commands).

A default DbContext context must exist, or a context factory must be provided

I'm getting the following error while performing "Bulk Insert" using EntityFramework extensions.
_indnCon.BulkInsert(_DataToTrans, operation => operation.IncludeGraph = true);
Exception occurs in the above line and here is the exception.
A default DbContext context must exist,
or a context factory must be provided (EntityFrameworkManager.ContextFactory).
This setting is required for some features like IncludeGraph.
Here I'm passing the Connection String to the DBContext manually.
using (InsightDataContext _indnCon = new InsightDataContext(_connectionString))
Can anyone help?
It seems that IncludeGraph feature needs to be able to create a new instance of your context, even if you already instantiated the context yourself in this scope. So, as the message says, you can try setting a default constructor for your context:
EntityFrameworkManager.ContextFactory = context => new CurrentContext(yourConnectionString);
The info comes from this post.

Why the default Controller implementation sends crashes with internal error?

I generated controller under rest-api grails app profile. Nothing is changed in controller, just some println calls added.
For call curl -X PUT -d name=petr2 -d phone=338 localhost:8080/TSCell/3 I have {"message":"Internal server error","error":500} response. In debug I can see, that error occured after final respond TSCell, [status: OK, view:"show"] call.
Code for update method:
#Transactional
def update(TSCell tSCell) {
println "in update method"
if (tSCell == null) {
transactionStatus.setRollbackOnly()
render status: NOT_FOUND
return
}
if (tSCell.hasErrors()) {
transactionStatus.setRollbackOnly()
respond tSCell.errors, view:'edit'
return
}
tSCell.save flush:true
respond tSCell, [status: OK, view:"show"]
}
And stack trace
ERROR org.grails.web.errors.GrailsExceptionResolver - IllegalArgumentException occurred when processing request: [PUT] /TSCell/3
Model variable [TSCell] of with value [class zcrm.api.TSCell] type [java.lang.Class] is not of the correct type [zcrm.api.TSCell]. Stacktrace follows:
java.lang.reflect.InvocationTargetException: null
at org.grails.core.DefaultGrailsControllerClass$ReflectionInvoker.invoke(DefaultGrailsControllerClass.java:210)
at org.grails.core.DefaultGrailsControllerClass.invoke(DefaultGrailsControllerClass.java:187)
at org.grails.web.mapping.mvc.UrlMappingsInfoHandlerAdapter.handle(UrlMappingsInfoHandlerAdapter.groovy:90)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doPut(FrameworkServlet.java:883)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55)
at org.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:77)
at org.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:67)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: grails.views.ViewRenderException: Error rendering view: Model variable [TSCell] of with value [class zcrm.api.TSCell] type [java.lang.Class] is not of the correct type [zcrm.api.TSCell]
at grails.views.AbstractWritableScript.writeTo(AbstractWritableScript.groovy:33)
at grails.views.mvc.GenericGroovyTemplateView.renderMergedOutputModel(GenericGroovyTemplateView.groovy:71)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303)
at grails.views.mvc.renderer.DefaultViewRenderer.render(DefaultViewRenderer.groovy:105)
at grails.artefact.controller.RestResponder$Trait$Helper.internalRespond(RestResponder.groovy:188)
at grails.artefact.controller.RestResponder$Trait$Helper.respond(RestResponder.groovy:98)
at zcrm.api.TSCellController$$EQ0icN2W.$tt__update(TSCellController.groovy:64)
at grails.transaction.GrailsTransactionTemplate$2.doInTransaction(GrailsTransactionTemplate.groovy:96)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
at grails.transaction.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:93)
at grails.transaction.GrailsTransactionTemplate$2.doInTransaction(GrailsTransactionTemplate.groovy:96)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
at grails.transaction.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:93)
... 14 common frames omitted
Caused by: java.lang.IllegalArgumentException: Model variable [TSCell] of with value [class zcrm.api.TSCell] type [java.lang.Class] is not of the correct type [zcrm.api.TSCell]
at grails.views.WritableScriptTemplate.make(WritableScriptTemplate.groovy:138)
at grails.plugin.json.view.api.internal.DefaultGrailsJsonViewHelper.prepareWritable(DefaultGrailsJsonViewHelper.groovy:736)
at grails.plugin.json.view.api.internal.DefaultGrailsJsonViewHelper$7.writeTo(DefaultGrailsJsonViewHelper.groovy:713)
at grails.plugin.json.view.JsonViewTemplate.json(JsonViewTemplate.groovy:126)
at grails.plugin.json.view.JsonViewTemplate.json(JsonViewTemplate.groovy:149)
at zcrm_api_TSCell_show_gson.run(zcrm_api_TSCell_show_gson:7)
at grails.plugin.json.view.JsonViewTemplate.doWrite(JsonViewTemplate.groovy:35)
at grails.views.AbstractWritableScript.writeTo(AbstractWritableScript.groovy:30)
... 26 common frames omitted
Thanks in advance.
That code shouldn't compile, but Groovy is too 'helpful' sometimes and allowed it through. You named an instance variable the same as its class, TSCell, and this turns out to be an interesting block of code to see how Groovy handles disambiguation between instance and static method calls.
For the first line, since you have TSCell TSCell it's possible for the compiler to know that the one on the left is the class name and the one on the right is an instance variable, since there's no other valid interpretation of those tokens.
In the third line it's not as clear whether the class or instance variable is being checked for null, but I tried this out locally and it's the instance variable.
TSCell.hasErrors() could be interpreted as a static method call on the class or a call on the instance, but since that method isn't static, Groovy invokes it on the instance and it succeeds. The same logic has to be applied to the save call, but again since it's not a static method it's call on the instance and succeeds.
And then on the last line of the method, kaboom, your luck ran out after four successful calls. There are a few overloads of the respond method and you end up calling respond(Object, Map), and that's valid for either TSCell the class, or TSCell the instance of the TSCell class. Groovy picked the one that wasn't what you intended and the one that isn't supported inside the respond method.
Groovy shares Java's variable and class naming conventions, i.e. class names start with an uppercase letter and instance variable names start with a lowercase letter. It's one thing to just tell people that this is a good approach, but an example like this makes it a lot more obvious why it's a bad idea to use uppercase instance variable names (you should be able to look at the variable and not need to see its declaration to know if it's a class or var name) and why it's even worse to use the same name as the class.
This error is probably caused because you named parameter with same name as class name.
I would suggest that you change name of the variable to lowercase (this is groovy and java naming convention).
def update(TSCell tsCell) { //you can also just write tsCell without type
println "in update method"
if (tsCell == null) {
transactionStatus.setRollbackOnly()
render status: NOT_FOUND
return
}
if (tsCell.hasErrors()) {
transactionStatus.setRollbackOnly()
respond tsCell.errors, view:'edit'
return
}
tsCell.save flush:true
respond tsCell, [status: OK, view:"show"]
}
The problem was in the call curl. As documentation says Grails has built in support for Content negotiation using either the HTTP Accept header, an explicit format request parameter or the extension of a mapped URI.
So the adding -H "Accept: application/xml" to the above curl call resolved the issue.

Registering a type with both EnableClassInterceptors and WithParameter

I'm having an issue with Autofac where it seems like EnableClassInterceptors is interfering with my ability to use .WithParameter(...). When the constructor is being called on Service using the code below, someString is not being populated. Notes:
I've tried using ResolvedParameter instead, it does not help (note: my Resolved parameter still includes the name of the parameter when I tried that)
If I remove EnableClassInterceptors and InterceptedBy, the parameter does get populated properly. This, however, isn't a valid solution as I need the interceptors.
Re-ordering WithParameter, EnableClassInterceptors, and InterceptedBy does not help.
Looking at Type Interceptors, specifically the "Class Interceptors and UsingConstructor" section, on docs.autofac.org, it mentions that using EnableClassInterceptors will cause ConstructUsing to fail. I think something similar might be happening with my scenario below.
Snippet of my registration code looks like this:
var builder = new ContainerBuilder();
builder.RegisterType<Dependency>.As<IDependency>.InstancePerLifetimeScope();
builder.RegisterType<Service>()
.As<IService>()
.WithParameter(new NamedParameter("someString", "TEST"))
.EnableClassInterceptors()
.InterceptedBy(typeof(LogExceptionsInterceptor));
Service's constructor looks something like this:
public class Service : IService
{
public Service(IDependency dependency, string someString)
{
if(dependency == null)
throw ArgumentNullException(nameof(dependency));
if(someString == null)
//**throws here**
throw ArgumentNullException(nameof(someString));
}
}
[Guess] What I'm thinking is happening is that when EnableClassInterceptors is called, a proxy class is generated with a constructor that works on top of the existing one, but the parameter names do not copy over into the proxy class/constructor.
Is this a problem? Is there a way to form the registration that allows both WithParameter and EnableClassInterceptors to be used together? Is it a bug in Autofac?
Your guess is correct: the generated proxy class does not keep the constructor parameter names.
Currently there is no way to influence this in DynamicProxy so this is not a bug of Autofac (although this edge case currently not documented on the Autofac documentation website).
This is how your original Service class's parameters look like:
typeof(Service).GetConstructors()[0].GetParameters()
{System.Reflection.ParameterInfo[2]}
[0]: {ConsoleApplication10.IDependency dependency}
[1]: {System.String someString}
But the generated proxy does not keep the names:
GetType().GetConstructors()[0].GetParameters()
{System.Reflection.ParameterInfo[3]}
[0]: {Castle.DynamicProxy.IInterceptor[] }
[1]: {ConsoleApplication10.IDependency }
[2]: {System.String }
So you have two not very robust options to workaround this limitation with WithParameter:
use the TypedParamter with string as the type:
.WithParameter(new TypedParameter(typeof(string), "TEST"))
However if you have multiple paramters with the same type this won't work
use the PositionalParameter in this case you need to add 1 if the type is proxied
.WithParameter(new PositionalParameter(2, "TEST"))
Another options would be to don't use a primitive string type but create a wrapper e.g. MyServiceParameter or create another service which can provide these string configuration values to your other services.

ArgumentException when creating instance of object that inherits from ObjectContext

I'm loosely following an excellent series of blog posts by Kazi Manzur Rashid as a learning exercise for learning how to implement some new (for me at least) design patterns, but I'm getting trouble from the start.
I've basically copied his code for the Database, RepositoryBase and RepositoryBaseTests classes, but when I try to run the tests, I get an error message saying
Unable to create instance of class Booking.Infrastructure.EntityFramework.Repositories.Tests.RepositoryBaseTests. Error: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.ArgumentException: Format of the initialization string does not conform to specification starting at index 0..
Through the debugger I have verified that the exception is thrown on the constructor for the Database class, which looks like this:
public Database(
IConfigurationManager configurationManager,
string connectionstringName)
: base(
GetConnectionString(configurationManager, connectionstringName),
"BookingEntities")
{ // Nothing happens here }
The error is thrown when calling the base constructor, and if I'd hard-code the values that I'm currently sending in, it would look like this:
: base("Dummy connStr", "BookingEntities")
Why doesn't this work?
"Dummy connStr" is not a valid EF connection string.
A valid EF connection string looks like:
connectionString="metadata=res://*/Data.Model.csdl|res://*/Data.Model.ssdl|res://*/Data.Model.msl;provider=System.Data.SqlClient;provider connection string="Data Source=SERVERNAME\SQLDEV2008;Initial Catalog=DBName;Integrated Security=True;MultipleActiveResultSets=True""