I have a little problem. I have application running on localhost and everything is OK, but when I upload it to production web server and I want to connect the database I get just "Sorry, an error occurred while processing your request.". When I try page without database interaction it works. I'm using Entity Framework, but I'm not sure if I have connection strings correct.
This is connection string for localhost:
<connectionStrings>
<add name="ApplicationServices" connectionString="data source=localhost\MSSQL;Integrated Security=SSPI;Initial Catalog=KravmagaIS" />
<add name="KravmagaISEntities" connectionString="metadata=res://*/Models.KravmagaModel.csdl|res://*/Models.KravmagaModel.ssdl|res://*/Models.KravmagaModel.msl;provider=System.Data.SqlClient;provider connection string="Data Source=ISKUDA-NTB\MSSQL;Initial Catalog=KravmagaIS;Integrated Security=True;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient" />
</connectionStrings>
and this one is for production server:
<connectionStrings>
<add name="ApplicationServices" connectionString="Data Source=192.168.1.5;User ID=db3542;Password=****;Initial Catalog=db3542" />
<add name="KravmagaISEntities" connectionString="metadata=res://*/Models.KravmagaModel.csdl|res://*/Models.KravmagaModel.ssdl|res://*/Models.KravmagaModel.msl;provider=System.Data.SqlClient;provider connection string='Data Source=192.168.1.5;User ID=db3542;Password=*****;Initial Catalog=db3542'" providerName="System.Data.EntityClient" />
</connectionStrings>
Is there any mistake? I'm sure that password is correct.
Thanks for helping.
EDIT:
Sorry my mistake. :-/ The connection is OK. But the relations in production server are the cause of the problem.
I have class Training and class Instructor. (Training has one instructor).
When I call in view:
#training.InstructorID
I get normaly the ID of training instructor, but when I call:
#training.Instructor.Fullname
I get the error message. On localhost is everything working.
Any ideas? Thanks.
I suppose that the same code runs in your development environment so it should not be a problem of your code. Also because you mentioned that Training is loaded it should not be a problem of connecting to the database server.
It looks like lazy loading is not working which turns back to my former note that MARS (MultipleActiveResultSets) is not enabled in the production connection string. MARS allows you to read results from one query in the loop and in the same time execute another query to get details. Typical example is:
// Executes something kile SELECT * FROM Trainings and has opened
// DataReated for the whole duration of the loop.
foreach(var training in context.Trainings)
{
// Executes something like SELECT * FROM Instructors WHERE Id = #Id
// and opens its own DataReader to get the result.
// If MARS is not enabled or not supported you will get an exception
var fullName = training.Instructor.FullName;
}
Btw. the code is example of N+1 problem because it will exacute 1 outer query and for each result of the outer query it will execute 1 inner query. So for N results from the outer query you it will execute N subqueries => THIS IS BAD and should be avoided as much as possible by using another loading technique. For example:
// Loads both trainings ana related instructors in the same query.
foreach(var training in context.Trainings.Include("Instructor"))
{
// No query is executed here because instructor is already loaded.
var fullName = training.Instructor.FullName;
}
Related
I have the following in my code:
DbContext = new DataContext();
DbContext.Configuration.AutoDetectChangesEnabled = false;
Then in my controller method:
// GET /api/Applications
public IEnumerable<Application> Get()
{
return _uow.Applications.GetAll().OrderBy(p => p.Name);
}
However I still get the following message:
System.InvalidOperationException was unhandled by user code
HResult=-2146233079
Message=The model backing the 'DataContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).
Source=EntityFramework
StackTrace:
Can someone explain why this is happening. I thought the line after my context creation would stop this check.
You can place (it's a static method)
Database.SetInitializer<DataContext>(null);
before you first use your DataContext. But take a note, that this will turn it off. Done. If your database is not compatible with model, your queries etc. will fail.
This is because you have some difference in database schema with your entity mode. The error is saying that you need to update the database schema according to the new model you have in the code.
AutoDetectChangesEnabled is not something related to this error. Because it is about tracking changes to the data while the error you are getting is related to the changes in database schema .
The error message is suggesting you to use code first migrations to update the database schema according to your changes in data model.
You have 2 options:
1. Set the Initializer of your context to null by placing this line in the constructor of your derived DbContext:
Database.SetInitializer<MyContext>(null);
2. Disable the Database Initializer in your Web.config file by adding a Key inside the appSettings node:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="DatabaseInitializerForType YourNamespace.YourDbContext, YourAssemblyName"
value="Disabled" />
</appSettings>
</configuration>
Replace YourNamespace.YourDbContext and YourAssemblyName with the corresponding value in your application.
I can't find how my connectionString syntax is wrong. Can anyone suggest a way to figure this out? I am having a difficulty using EF with my connection string. I am new to EF.
I am using Sybase Anywhere 12 database.
I'm using the Table-First ObjectContext with EDMX in a separate class library refenced by a web application.
I'm using a Ninject Module in my class library to bind my repositories.
I'm using a ODBC DataStore called "Test"
Other information EF 4.3.1.0, .NET 4, VS2010
My main web application web.config has the EF connection string copied to it as:
<connectionStrings>
<add name="Entities"connectionString="metadata=res://*/MyEntities.csdl|res://*/MyEntities.ssdl|res://*/MyEntities.msl;provider=iAnywhere.Data.SQLAnywhere;provider connection string="UserID=aUser;Password=aPassword;DataSourceName=Test"" providerName="iAnywhere.Data.SQLAnywhere"/>
</connectionStrings>
When I initialize my Entity/ObjectContext in my Repository (see using statement below) it returns an error: "The specified named connection is either not found in the configuration, not intended to be used with the EntityClient provider, or not valid."
using (var context = new Entities())
{
return {Linq to Entity here}
}
I turned on CLR exceptions on the debugger and found the code throws the error in the .NET Framework here:
EntityConnection.cs
effectiveConnectionOptions = new DbConnectionOptions(setting.ConnectionString, EntityConnectionStringBuilder.Synonyms, false);
edmx designer generated:
/// <summary>
/// Initializes a new Entities object using the connection string found in the 'Entities' section of the application configuration file.
/// </summary>
public Entities() : base("name=Entities", "Entities")
{
this.ContextOptions.LazyLoadingEnabled = true;
OnContextCreated();
}
I can see my connection string there, so it is having a difficult time parsing the connectionString. I have tried many different permutations of syntax and haven't found anything it accepts including:
Explicitly naming the assembly for entity files instead of a wildcard(e.g. metadata=res://MyDomain/MyEntities.csdl...)
Using Sybase friendly ODBC attributes such as UID instead of UserID, PWD instead of Password, and DBN instead of DataSourceName.
Thanks.
I got everything working and the only reason I can think of is that I deleted my ASP .NET 4.0 temp files. Also, I must add I changed my process from using an integration test to test this piece to using a unit test. I did not do unit tests first, because our build server does not have a database on it.
Once I was able to prove that it was working there, I decided to delete my temp files. After that, everything started working properly. So, some sort of cache issue was occurring in my application. I used the same connectionString that I mentioned above.
Actually, I used the domain name of the Metadata "metadata=res://MyDomain/MyEntitities.csdl" rather than */MyEntities.csdl. I don't plan on changing the domain any time soon. In fact, that is just what may have caused some of the issue, because I had changed the location, name, and namespace of MyEntities.Domain where the EF was.
I've mapped some function that is being used as a wrapper for the one of the Oracle functions (I really need to call that Oracle function from my LINQ).
My mapping looks like (Storage Model):
<Function Name="RunTranslate" IsComposable="false" BuiltIn="false">
<CommandText>
SELECT Translate(#DataToTranslate using char_cs) AS ResultData FROM dual
</CommandText>
<Parameter Name="DataToTranslate" Type="char" Mode="In" />
</Function>
And:
<FunctionImport Name="OracleTranslate" ReturnType="Collection(String)">
<Parameter Name="DataToTranslate" Mode="In" Type="String" />
</FunctionImport>
I try to use it from the code this way:
using (var context = new TestEntities())
{
....
var result = from myData in context.OracleTranslate("test")
select myData; // Error ORA-00936!
....
}
I tried to use Entity Framework Profiler (EFProf) to see the query that is actually being sent to the DB. Intercepted query is the next:
SELECT Translate('test' /*#DataToTranslate*/ using char_cs) AS ResultData FROM dual
(looks fine)
But my application stops with the next error:
ORA-00936: missing expression
If I copy-paste the intercepted query into the VS2010's Server Explorer Query Window - it works! DB returns correct data to me!
So, where the problem can be? What is the difference between the code and the query window in my case? I thought they use the same provider, etc...
Thank you very much!
EDIT:
I've just used standard Inet-sniffer to check the real data that is being sent over the sockets and Internet when I run my query.
And it's not the same with the first one! It's exactly my source SQL query:
SELECT Translate(#DataToTranslate using char_cs) AS ResultData FROM dual
It seems, that parameter is not recognized, but why?
I've found a solution, I hope this info will help someone:
DataToTranslate parameter should be mapped with the colon symbol (":DataToTranslate"), not "#".
Another important experience (as to me): Entity Framework Profiler (EFProf) shows something that it wants, not the real data - much better to use TCP-sniffers like Wireshark to see that data.
I have several databases, the schema of them are same. When I use database-first, the connection string is specified when I create the edmx file. I want to know, is there a way to change the connection string? This is, so I can choose which database to operate.
We do not store connection strings in our web.configs, so the accepted solution would not work for us. If you simply attempt to provide the connection string via the base DbContext constructor, you'll get the following exception:
Code generated using the T4 templates for Database First and Model First development may not work correctly if used in Code First mode. To continue using Database First or Model First ensure that the Entity Framework connection string is specified in the config file of executing application. To use these classes, that were generated from Database First or Model First, with Code First add any additional configuration using attributes or the DbModelBuilder API and then remove the code that throws this exception.
To resolve this, create a partial class of your context as follows and format your connection string with the additional EF metadata (where MyContext is your context model name (e.g. your model name is MyModel.edmx, than the MyContext in code below is replaced with MyModel with all three extensions .csdl, .ssdl, .msl used)):
public partial class MyContext
{
public MyContext(string connStr)
: base(string.Format(#"metadata=res://*/MyContext.csdl|res://*/MyContext.ssdl|res://*/MyContext.msl;provider=System.Data.SqlClient;provider connection string='{0}'", connStr))
{
}
}
Change the connection string in the web.config file.
<connectionStrings>
<add name="SandBoxEntities" connectionString="metadata=r... />
</connectionStrings>
I abbreviated the actual connection string because it isn't important -- just wanted to give you an idea of what to look for in the web.config file.
You can also change your connection strings programatically. Check out Example 16.2. Programmatically modifying an EntityConnectionString.
You can define multiple connection string in web.config and then use them in your code perhaps your job.
for example:`
<connectionStrings>
<add name="conStr1" connectionString="metadata=r... />
</connectionStrings>`
<connectionStrings>
<add name="conStr2" connectionString="metadata=r... />
</connectionStrings>`
and so on
and your context class constructor get connection string name as parameter:
public MyContext(string connStr)
: base(connStr) { }
Ok. now you can use in your code as below:
using (var db = new MyContext("name=conStr1"))
{
//your code here
}
and then
using (var db = new MyContext("name=conStr2"))
{
//your code here
}
I am using EF 4.1, and I create a normal EF edmx file.
I generate it from a DB.
When it's been generated I rightclick and select add code generation item, to generate new classes, and use the DbContext instead. I use the template DbContext generator.
Everything works fine.
Then I trie to query the context:
using (var context = new PasDBEntities())
{
var client=context.ClientCompanies.SingleOrDefault(_=>_.ID==clientCompanyId);
if(client!=null)
I have no problem creating a new instance of the context but when I try to query it the problem occur. I get stuck on the UnintentionalCodeFirstException.
And gets the error:
{"Code generated using the T4 templates for Database First and Model First development may not work correctly if used in Code First mode. To continue using Database First or Model First ensure that the Entity Framework connection string is specified in the config file of executing application. To use these classes, that were generated from Database First or Model First, with Code First add any additional configuration using attributes or the DbModelBuilder API and then remove the code that throws this exception."}
I don't want to use code first, but I don't know if I can "switch" it off, or where the problem is.
For reference, here is my constructor ...
public partial class PasDBEntities : DbContext
{
public PasDBEntities()
: base("PasDBEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
...and connection string:
<connectionStrings>
<add name="PasDBEntities"
connectionString="metadata=res://*/PasDB.csdl|
res://*/PasDB.ssdl|
res://*/PasDB.msl;
provider=System.Data.SqlClient;
provider connection string="
data source=localhost;
initial catalog=PasDB;
integrated security=True;
pooling=False;
multipleactiveresultsets=True;
App=EntityFramework""
providerName="System.Data.EntityClient" />
</connectionStrings>
I see you are using the EDMX with Templates (.tt) for generating the classes. But if you are getting the information from a existing database, the wizard will create a ConnectionString compatible with ObjectContext (metadata informations and provider of entityframework).
The problem is that the connectionstring you are using is for ObjectContext (Database First and Model First). For the DbContext you should use the connectionstring without the metadata informations.
Your connection string should be:
<connectionStrings>
<add name="PasDBEntities"
connectionString="data source=localhost;
initial catalog=PasDB;
integrated security=True;
pooling=False;
multipleactiveresultsets=True;
App=EntityFramework"
providerName="System.Data.SqlClient" />