MVC - Context always uses the default connection string - sql

I am looking to pick up MVC after previously working with web forms and I have been doing the movie tutorial over at asp.net but I am having an issue that is utterly confusing.
I have 2 connection string in my web config:
<connectionStrings>
<add name="MovieDBContext"
connectionString="Data Source=(LocalDB)\(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Movies.mdf;Integrated Security=True"
providerName="System.Data.SqlClient" />
<add name="DefaultConnection" connectionString="Data Source="(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\aspnet-MvcMovie-20160408044847.mdf;Initial Catalog=aspnet-MvcMovie-20160408044847;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
I then have my context (Note I have tried setting the connection string here too after another answer on stack although I believe it should do it automatically if the context name is the same as the connection string name
public class MovieDBContext : DbContext
{
public MovieDBContext() : base("MovieDBContext"){ }
public DbSet<Movie> Movies { get; set; }
}
Whatever I do it uses the default connection string rather than the MovieDbContext connection string and for the life of me I cant work out why. If I set the data source of the default connection string to the datasource of the moviedbcontext one it works as it should and connects to the right database but I cant work out why it will ONLY use the default one (I have even tried changing the names of the connection string and the context to no avail)
Any help appreciated
Cheers

Try commenting the call to the base constructor in your derived DbContext class and just let the default constructor be called. Be sure that your web.config entry for the connection is in the root web.config file of the application and that it conforms to the expected naming conventions (see further down for more info).
public class MovieDBContext : DbContext
{
//// comment the call to the base constructor
// public MovieDBContext() : base("MovieDBContext"){ }
public DbSet<Movie> Movies { get; set; }
}
The MSDN documentation at https://msdn.microsoft.com/en-us/library/gg679577%28v=vs.103%29.aspx provides information about the convention used to determine the database name.
protected DbContext()
Constructs a new context instance using conventions to create the name of the database to which a connection will be made. By convention the name is the full name (namespace + class name) of the derived context class. For more information on how this is used to create a connection, see the remarks section for DbContext.

Related

Getting 'Context is not constructible. Add a default constructor or provide an implementation of IDbContextFactory."

I am getting this error when I try to use code first migrations.
My context has a constructor with the connection name.
public class VeraContext : DbContext, IDbContext
{
public VeraContext(string NameOrConnectionStringName = "VeraDB")
: base(NameOrConnectionStringName)
{
}
public IDbSet<User> Users { get; set; }
public IDbSet<Product> Products { get; set; }
public IDbSet<IntCat> IntCats { get; set; }
}
This connection name is injected with ninject when the project runs, I have also specified it as a default as in the above code but this did not help.
kernel.Bind<IDbContext>()
.To<VeraContext>()
.WithConstructorArgument("NameOrConnectionStringName", "VeraDB");
When I try to add migrations with "Enable-Migrations" is throws up the error:
The target context 'VeraData.EF.Infrastructure.VeraContext' is not
constructible. Add a default constructor or provide an implementation
of IDbContextFactory.
If I remove the constructor from VeraContext it will work but creates another database with VeraData.EF.Infrastructure.VeraContext as its name.
I presume that ninject only passes the connection string when the project runs and not when I use code first migrations. Anyway I can inject/provide a default for the connection name when using code first migrations ?
Essentially you need a default ctor (that's the error) - but just implementing it would lead to problems.
You'd have to implement the IDbContextFactory for the results to be consistent (or your migration from code won't work etc.).
Migrations actually call your default constructor to make a
connection. So you're other ctor won't matter much.
Here is the basic factory...
public class MyContextFactory : IDbContextFactory<MyContext>
{
public MyContext Create()
{
return new MyDBContext("YourConnectionName");
}
}
You should combine that with injection, to inject and construct your DbContext as you wish.
If you don't want to spend time looking into the IDbContextFactory option, and to get things working create a default constructor and hard-code the name of the connection string when calling the base DbContext:
public class CustomContext : DbContext
{
public CustomContext() :base("name=Entities") {}
}
SRC: http://www.appetere.com/Blogs/SteveM/April-2012/Entity-Framework-Code-First-Migrations
To complement #nccsbim071 answer, I have to add one more thing... this option doesn't like constructor with default parameters... for instance:
public MyContext(bool paramABC = false) : base("name=Entities") {...}
instead you have to create a non-parameter (default) constructor and the parameter-constructor like old fashion way.
public MyContext() :base("name=Entities") {...}
public MyContext(bool paramABC) : this() {...}
NOTE:
Entities in this case means the connection string name... By convention, the name of the context is the same as the connection string name and since MyContext is not the same as Entities, it's necessary specify it manually.
In my situation I wanted to use the default connection factory, instead of explicitly providing one. Somewhere inside EF6 it'll try to lookup the factory, but it fails with this exception message. Stepping through the EF6 code, I found that Glimpse.Ado was wrapping the connection factory, which made the lookup fail to find a match.

EF 5 + Azure + MigrationFirst overrides database name. Why?

I created a database in Azure setting my own custom name. I then created EF 5 code first entities and added migrations. On application startup I called these two lines:
Database.DefaultConnectionFactory = new SqlConnectionFactory(connectionString);
Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDataContext, MyConfiguration>());
Connection string is taken straight from Azure:
Server=tcp:xxx.database.windows.net,1433;Database=dbName;User ID=yyy;Password=zzz;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;
On fist call I expected database dbName to be filled with tables according to POCO schema.
But instead a NEW database is generated with the complete namespace name of my context:
MyService.Business.Entity.MyContext
Why will the migration not accept the database name specified in the connection string?
You can specify the Database name or connection string name in the constructor of your DbContext:
public class MyDataContext : DbContext
{
public MyDataContext: base("DbNameOrConntectionStringNameHere")
{
}
}
My experience is that, in the case where the connection string is being passed in code, rather than obtained from app.config, EF is quirky about how it obtains the connection string.
I had to add a class that inherited from IDBContectFactory
public class ContextFactory : IDbContextFactory<Context>
{
public Context Create()
{
var s = (string)AppDomain.CurrentDomain.GetData("ConnectionString");
var context = new Context(s);
return context;
}
}
Also, in order to create a migration, I needed the following in my context class
// uncomment when creating migration - comment out after migration is created
public Context() : base("ConnectionStringName"){}
Where the ConnectionStringName is set up in my app.config.
I am still mystified that I had to do this and have asked about it here

Entity framework, multiple edmx to share connection string - is it possible?

I saw a number of related questions but none of them is exactly what I am looking for.
We are using one database and need to have separated edmx files, with different Model and ObjectContext class names. This results in having multiple connections string, which are different only in metadata part.
For now I ended up doing this:
Web.config
<connectionStrings configSource="connectionStrings.config"></connectionStrings>
connectionStrings.config
<connectionStrings>
<add name="Entities" connectionString="metadata=res://*/Entity.Model.csdl|
res://*/Entity.Model.ssdl|res://*/Entity.Model.msl;
provider=CONNECTION STRING DATA GOES HERE"/>
<add name="TwoEntities" connectionString="metadata=res://*/TwoEntity.TwoModel.csdl|
res://*/TwoEntity.TwoModel.ssdl|res://*/TwoEntity.TwoModel.msl;
provider=EXACTLY THE SAME CONNECTION STRING DATA GOES HERE"/>
</connectionStrings>
In my ObjectContext derived classes I do have the default generated constructors:
public Entities()
: base("name=Entities", "Entities")
{
}
and
public TwoEntities()
: base("name=TwoEntities", "TwoEntities")
{
}
What would be very nice is not to have two connection strings in .config file, but share the same connection sting from this file and somehow override the metadata part of it in each class.
Any suggestions on how to do this?
Yes it is possible but you cannot use EF connection string from configuration. You must built connection string manually in the application. ObjectContext supports multiple overloaded constructors. One of the is accepting EntityConnection. EntityConnection in turn can be constructed from MetadataWorkspace (class created from your EF metadata files) and DbConnection. You can add custom factory method to your derived context which will build MetadataWorkspace and DbConnection from shared DB connection string and pass them in EntityConnection.
public static Entities GetContext(string connenctionString)
{
MetadataWorkspace workspace = GetWorkspace(); // This should handle workspace retrieval
DbConnection connection = new SqlConnection(connectionString); // Connection must not be openned
EntityConnection entConnection = new EntityConnection(workspace, entConnection);
return new Entities(entConnection);
}
private Entities(EntityConnextion entConnection) : base(entConnection)
{ }
You will use this factory method instead of constructor. Make sure that GetWorkspace creates MetadataWorkspace only once per metadata set and store it internally for the lifetime of the application. Its creation is time consuming.

WCF and interfaces

I need to have 2 families of classes (one on server and one on client side) which are identical in data structure but differs in behavior. Also I suppose that these fmailies will be enough big, thus I don't want to implement intermediate level of DTO and transformations into and from it.
I decided to move in following manner: declare shared assembly with declaration of data and services interfaces like these ones:
public interface ITest
{
string Title { get; set; }
int Value { get; set; }
}
public interface IService
{
ITest GetData();
}
Having these declarations I can implement these interfaces on server side for example basing on Entity Framework (data) and WCF (services). On the client side I can use for example Dependency Properties (data) and WCF (service).
When I started trying to implement this, I met several troubes.
First one was about server side of WCF - it simply do not want to work with interfaces as return parameters. Thanks to StackOverflow this issue was resolved like here
.
Next problem is that XML rendered by server side includes qulified assembly name of serialized on the server class.
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<GetDataResponse xmlns="http://tempuri.org/">
<Test z:Id="1" z:Type="Dist.Server.Model.Test" z:Assembly="Dist.Server, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" xmlns="http://schemas.datacontract.org/2004/07/Dist.Server.Model" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
<Title z:Id="2">Test</Title>
<Value>123</Value>
</Test>
</GetDataResponse>
</s:Body>
</s:Envelope>
Thus during deserialization on client side there was an attempt to load this type. As this type is inaccessible on client side, I had to implement some kind of type mapping. I found that this is quite easy as NetDataContractSerializer used for serialization supports Binder property. Thus I override this property on client side and return correct value (hardcode in meantime, but it's OK for tests).
public class NetBinder : SerializationBinder
{
public override Type BindToType(string assemblyName, string typeName) {
var type = Type.GetType("Client.Test, Client, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");
return type;
}
}
Now I have following picture:
- Server uses NetDataContractSerializer to serialize response. It uses actual value (calss) during serialization instead of type used in declaration of service (interface).
- Client side receives XML and starts deserialization. To resolve type, NetDataContractSerializer calls my Binder that returns correct type.
- NetDataContractSerializer creates instance of correct type and starts loading of its properties.
And here I got a trouble that I don't know how to resolve. Values of properties are not deserialized. It means that instance of class is created correctly (uninitialized instance created through reflection services), but all properties are in their default values (0 or null).
I tried to play with declaration of class on client side: mark it as [Serializable], implement ISerializable, etc., but nohing is helpful. NetDataContractSerializer requires class to be marked as [DataContract] or [Serializable]. First option leaves properties empty, second one causes exceptions like "</Test> is unexpected, expected is bla-bla-bla_Value_Ending_bla-bla-bla".
Does anybody have any suggestions on how to resolve this last step?
I can provide full sources for better understanding, but I don't know ifI can attach them here...
Thanks in advance.
You could have a look at frameworks like AutoMapper that would take care the transformation to and from DTO. This would make your life much easier.
Instead of using an interface why not create a base class containing only the data and inherit it on both sides by sharing the assembly containing this class. Playing around with the ServiceKnownType should help you fix the last issues.
You may also share the same base classes on both sides and implement the specific logic as extension methods.
Seems that problem was solved enough easily. I created own serializer and used it instead of NetDataContractSerializer. Code is quite simple:
public class MySerializer: XmlObjectSerializer
{
public override void WriteStartObject(XmlDictionaryWriter writer, object graph) {
}
public override void WriteObjectContent(XmlDictionaryWriter writer, object graph) {
var formatter = new XmlSerializer(graph.GetType());
formatter.Serialize(writer, graph);
}
public override void WriteEndObject(XmlDictionaryWriter writer) {
}
public override object ReadObject(XmlDictionaryReader reader, bool verifyObjectName) {
var realType = Type.GetType("Client.Test, Client, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"); //temporary solution
var formatter = new XmlSerializer(realType);
return formatter.Deserialize(reader);
}
public override bool IsStartObject(XmlDictionaryReader reader) {
return true;//temporary solution
}
}
I checked SOAP that goes from server to client and it's almost the same as NetDataSerializer renders. The only difference is in attribute xmlns="".
Kai, Johann thanksfor your tries.

How to change configs in Spring.Net

An advantage of an IoC container is that you can swap in a mock service at the bottom of your object graph. However this seems much harder to do in Spring.Net than in other IoC Containers. Here's some code that does it in Unity and has Spring.Net code;
namespace IocSpringDemo
{
using Microsoft.Practices.Unity;
using NUnit.Framework;
using Spring.Context;
using Spring.Context.Support;
public interface ISomeService
{
string DoSomething();
}
public class ServiceImplementationA : ISomeService
{
public string DoSomething()
{
return "Hello A";
}
}
public class ServiceImplementationB : ISomeService
{
public string DoSomething()
{
return "Hello B";
}
}
public class RootObject
{
public ISomeService SomeService { get; private set; }
public RootObject(ISomeService service)
{
SomeService = service;
}
}
[TestFixture]
public class UnityAndSpringDemo
{
[Test]
public void UnityResolveA()
{
UnityContainer container = new UnityContainer();
container.RegisterType<ISomeService, ServiceImplementationA>();
RootObject rootObject = container.Resolve<RootObject>();
Assert.AreEqual("Hello A", rootObject.SomeService.DoSomething());
}
[Test]
public void UnityResolveB()
{
UnityContainer container = new UnityContainer();
container.RegisterType<ISomeService, ServiceImplementationB>();
RootObject rootObject = container.Resolve<RootObject>();
Assert.AreEqual("Hello B", rootObject.SomeService.DoSomething());
}
[Test]
public void SpringResolveA()
{
IApplicationContext container = ContextRegistry.GetContext();
RootObject rootObject = (RootObject)container.GetObject("RootObject");
Assert.AreEqual("Hello A", rootObject.SomeService.DoSomething());
}
[Test]
public void SpringResolveB()
{
// does not work - what to do to make this pass?
IApplicationContext container = ContextRegistry.GetContext();
RootObject rootObject = (RootObject)container.GetObject("RootObject");
Assert.AreEqual("Hello B", rootObject.SomeService.DoSomething());
}
}
}
For the benefit of Spring, the following needed to be in the App.config file. Clearly this only serves the first spring test, and not the second. Can you put multiple spring configurations in the config file? If so, what is the syntax and how do you access them? Or is there another way to do this?
<configSections>
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
</sectionGroup>
</configSections>
<spring>
<context>
<resource uri="config://spring/objects"/>
</context>
<objects xmlns="http://www.springframework.net">
<object name="RootObject" type="IocSpringDemo.RootObject, IocDemo" autowire="constructor" />
<object name="service" type="IocSpringDemo.ServiceImplementationA, IocDemo" autowire="constructor" />
</objects>
</spring>
Update
Here is a partial answer based at code at the links that Marko Lahma gave to Mark Pollack's blog. I have the above tests passing, with the following code:
public static class SpringHelper
{
public static T Resolve<T>(this IApplicationContext context, string name)
{
return (T)context.GetObject(name);
}
public static void RegisterType<T>(this GenericApplicationContext context, string name)
{
context.RegisterType(name, typeof(T));
}
public static void RegisterType(this GenericApplicationContext context, string name, Type type)
{
IObjectDefinitionFactory objectDefinitionFactory = new DefaultObjectDefinitionFactory();
ObjectDefinitionBuilder builder = ObjectDefinitionBuilder.RootObjectDefinition(objectDefinitionFactory, type);
builder.SetAutowireMode(AutoWiringMode.AutoDetect);
context.RegisterObjectDefinition(name, builder.ObjectDefinition);
}
}
...
[Test]
public void SpringResolveA()
{
GenericApplicationContext container = new GenericApplicationContext();
container.RegisterType<RootObject>("RootObject");
container.RegisterType<ServiceImplementationA>("service");
RootObject rootObject = container.Resolve<RootObject>("RootObject");
Assert.AreEqual("Hello A", rootObject.SomeService.DoSomething());
}
[Test]
public void SpringResolveB()
{
GenericApplicationContext container = new GenericApplicationContext();
container.RegisterType<RootObject>("RootObject");
container.RegisterType<ServiceImplementationB>("service");
RootObject rootObject = container.Resolve<RootObject>("RootObject");
Assert.AreEqual("Hello B", rootObject.SomeService.DoSomething());
}
This raises a few questions to me:
I want to integrate this technique into existing code that uses the usual container. Why do I have to use a different container type, GenericApplicationContext in this case? What if I want to read data into this object from the existing spring config in app.config or web.config? Would it work as the usual context? Could I then write data over these registrations with code?
How can I specify that ISomeService is to be created as a singleton? I don't mean supply a singleton instance to the container, but the container to create the instance, resolving its constructor, and use it when that type is needed.
how can I do the equivalent of container.RegisterType<ISomeService, ServiceImplementationA>(); ? I want to register type mappings to use in all cases where that type is needed by a constructor.
What exactly does container.RegisterType<ServiceImplementationA>("service"); do? It seems to register ServiceImplementationA as the implementation of ISomeService but ISomeServiceis never mentioned, so there could be ambiguity. e.g. what if ServiceImplementationA implemented more than one interface.
What is the string name given to the registration for? It won't work with en empty string, but it doesn't seem to matter what it is.
Am I trying to use spring in a way that it just does not work? I'm trying to use it like other IoC containers, but it's not quite working.
Adding as new answer trying to address the open points...
I want to integrate this technique
into existing code that uses the usual
container. Why do I have to use a
different container type,
GenericApplicationContext in this
case? What if I want to read data into
this object from the existing spring
config in app.config or web.config?
Would it work as the usual context?
Could I then write data over these
registrations with code?
Spring has concrete application context implementations for different kind of initialization tactics. The most common ones to use are GenericApplicationContext (manual), XmlApplicationContext (XML files) and WebApplicationContext (very much like XmlApplicationContext but tailored for web use). They all implement common interface: IApplicationContext which is the preferred way to access these containers.
Unfortonately altering registrations with code usually means that you need to use the specific sub-class directly. With GenericApplicationContext and StaticApplicationContext this is quite natural but XmlApplicationContext is usually considered to be XML only and this ways "fixed" to XML definition.
How can I specify that ISomeService is
to be created as a singleton? I don't
mean supply a singleton instance to
the container, but the container to
create the instance, resolving its
constructor, and use it when that type
is needed.
Your SpringHelper does just that, by default all objects in Spring are singletons. You could alter this behavior by calling ObjectDefinitionBuilder's SetSingleton method with false.
how can I do the equivalent of
container.RegisterType(); ? I want to
register type mappings to use in all
cases where that type is needed by a
constructor.
Spring uses object names (ids) to distinct between different implementations. So if you want to get specific type to serve a specific instance in case that there are many alternatives you should refer to this specific instance by name. If you are using autowiring and your object has dependency to interface ISomeService and there's only one object registered that implements it, the autowiring can set it without ambiguity.
What exactly does
container.RegisterType("service");
do? It seems to register
ServiceImplementationA as the
implementation of ISomeService but
ISomeServiceis never mentioned, so
there could be ambiguity. e.g. what if
ServiceImplementationA implemented
more than one interface.
Continuing from previous answer, this registers singleton of type ServiceImplementationA with name "service". This object comes autowiring candidate with all it's implemented interfaces (and with it's concrete type of course).
What is the string name given to the
registration for? It won't work with
en empty string, but it doesn't seem
to matter what it is.
It matters a great deal as explained earlier. The name is unique id within that context (parent context could have object with same name) and can be used to access specific object registrations. In short where other frameworks may associate a type as key to object registration, Spring uses name.
That's a bit apples and oranges comparison as the unit test uses code configuration for Unity and XML (app.config) configuration for Spring.NET.
If you go the XML route, then you can either comment out old implementation A and define the B implementation as the one to use - that what's configuration is all about right? Other option is to have dedicated XML files for each scenario (configuration setup) and include them via context's resource definitions (you have inline resource now). Other options include file system and assembly, see the web configuration section in Spring.NET's manual for a nice example.
If you go the code configuration route I would suggest to check Spring.NET Recoil and upcoming CodeConfig.