I'm working through the Building an MVC 3 App with Code First and Entity Framework 4.1 tutorial on MSDN and got stuck on "Also by default, this database will be a SQL Express database with the name derived from the strongly typed name of the context and its file will be in the SQL Express default data folder."
If I want to change the default (e.g. to place the MDF file in my App_Data folder) how would I do that? I will have several different contexts (one for each major functional area) and would like them all to live in the same database.
You define where the database lives using the web.config file connection settings.
You just have to make the Context Name = your connection string name so if the of you Context is MyContext you could define the location as below:
<connectionStrings>
<clear/>
<add name="MyContext"
connectionString="Server=myServer;Database=MyDB;Uid=foo;Password=XXX; "
providerName="System.Data.SqlClient"
/>
</connectionStrings>
In answer to your second question...
"I will have several different contexts (one for each major functional area) and would like them all to live in the same database."
Why not try...
MyContext.cs
public partial class MyContext : DbContext
{
}
FooContext.cs
partial class MyContext
{
public DbSet<Foo> Foos { get; set; }
}
BarContext.cs
partial class MyContext
{
public DbSet<Bar> Bars { get; set; }
}
You'll end up with one context and one connection, but your code is split over multiple files. Hopefully that's what you are trying to achieve.
Related
Problem:
You have an existing database that you want to use with EntityFrameworks so that you can make database changes via classes. You also want to be able to use the migration features to switch between versions of the database.
Unfortunately this doesn't work out of the box with an existing database, but you can use the Reverse POCO generator to reverse-engineer your db as if you wrote it from scratch.
Hopefully my step-by-step solution will benefit others, I'm sure I'll be referring to it again in 6 months.
Create new project called MyEF (class library project)
Install the EntityFramework Reverse POCO generator either from here, or within Visual Studio menu Tools|Extensions and Updates menu. select Online|Visual Studio Gallery|Templates|Visual C#|Database, install the EntityFramework Reverse POCO generator.
Using Package Manager console, install EntityFramework by Install-Package EntityFramework
Add a new C# item called MyDB.tt using the template: EntityFramework Rever POCO Code First Generator
Add a connectionStrings section to the app.Config class and point to your database.
e.g.
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=CP8;Initial Catalog=TestDB;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=False;" providerName="System.Data.SqlClient" />
</connectionStrings>
In the file MyDB.tt, change "MyDbContext" to "DefaultConnection" or whatever your connection name is. Save the TT file and the Reverse POCO generator will reverse engineer the database and build your code-first classs for you.
If your database has a _MigrationHistory table, delete it!
In the package manager console (PMC) issue the following
Enable-Migrations –EnableAutomaticMigrations -Force
add-migration Initial
Go to your migrations folder and replace the contents of your XXX_Initial.cs class with
namespace MyEf.Migrations
{
using System;
using System.Data.Entity.Migrations;
public partial class Initial : DbMigration
{
public override void Up()
{
}
public override void Down()
{
}
}
}
From the PMC, issue: update-database
Change your Model by editing the adding a new property in MyDb.cs to the MyTable class:
// MyTable
public class MyTable
{
public int Id { get; set; } // Id (Primary key)
public string Name { get; set; } // Name
public string Sex { get; set; } // Sex
public int? Age { get; set; } // Age
public bool AmIAwesomeOrWhat { get; set; }
}
Rebuild the solution
Issue a command to save your new migration, and update the database
add-migration MyNewProperty
update-database
The following commands will switch to whatever Migration you want.
update-database -targetmigration:Initial
update-database -targetmigration:MyNewProperty
I have created model classes and using following context in my mvc project on VS2013 and using EF 6.1
public class DataBase : DbContext
{
public class DataBase : DbContext
{
public DataBase()
: base("Db")
{
}
public DbSet<table> table{ get; set; }
}
}
"Db" is my connection string everything ,everything run good but table are not created on my database
Did you try this?
public class DataBase : DbContext
{
public class DataBase : DbContext
{
public DataBase()
: base("Name=Db")
{
}
public DbSet<table> table{ get; set; }
}
}
Set :base() to "Name=Db".
In ef 6 they changed how things work and therefore you need to do some manual steps to be able to generate the database. You have a couple of options I think:
1. Use the packed manager console and run the Update-DataBase command. (You'll have to figure out which flags to use) This might require you to make a blank db with the expected name before running update.
2. Change your database initializer command to:
Database.SetInitializer<UserDbContext>(new MigrateDatabaseToLatestVersion<UserDbContext, Configuration>());
This should make your code always update/create the database. Probably not what you want for production environment though..
3. You create your own initializer, which also has the benefit of seeding data to database on creation. Have a look at http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application <-- towards the end of the article there is an example of such an initializer. The chapter heading is "Set up EF to initialize the database with test 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" />
I am using DB First EF 4.1 and I am adding DbContextGenerator tt template to my model. This is all great, but I end up with classes like this:
public partial class t_city
{
public t_city()
{
this.t_neighborhood = new HashSet<t_neighborhood>();
}
public int city_id { get; set; }
public string city_name { get; set; }
public virtual ICollection<t_neighborhood> t_neighborhood { get; set; }
}
This is super ugly. I modified the template to generate properties in camelcase, but that breaks the mapping onto tables and columns. Is there way to get clean class names and still preserve the mapping?
EDIT
Looks like it's possible by renaming the objects inside the Entity Model file. The only question remains, is it possible to automate the renaming using a function, or does it have to be done manually each time?
Thanks!
You need to do it manually but that's needed only once for each entity / property. These changes are not deleted when you update your model from the database.
The only automation can be implemented as some processing of EDMX file. It is XML with defined schema so you can process that XML in your custom tool or XSLT transformation and automatically change property and entity names in CSDL and MSL.