I am working on some project at the moment and I have to use local database. So, I created a new service-based database (no tables atm). Then I wanted to add Entity Framework support.
Because I never used Entity Framework before, I was referring to that link: http://msdn.microsoft.com/en-us/data/jj200620.aspx.
Everything is OK, but here it gets complicated. I created my DataContext class with DbSet inside it. But, when I run my unit test, table is created on Localdb (not inside my .mdf file).
What to do?
I am pretty sure, that I did choose which database to use correctly (actually did that 3 times already), but still, data tables are created on LocalDb. What I am doing wrong here?
I am complete beginner with that (been only using doctrine ORM). Otherwise I can insert data and all, it is just on the wrong database.
When your doing code first development in EF, you can force EF to only ever consider one connection string name.
One of the constructors (of which there are quite a few overloads) on the EF Data Context parent classes, takes a simple string.
This string is given to be the name of a connection string in the App or Web config to use.
You make the call something like this:
using System.Data.Entity;
namespace MSSQL_EFCF.Classes
{
public class DataAccess : DbContext
{
public DataAccess() : base("myConnectionString")
{}
public DbSet<MyTableObject> MyObjects { get; set; }
}
}
You can still put any code you need for your own start-up (Such as DB Initializer calls) inside your constructor, and all that will get called once the base call completes.
The advantage of doing things this way forces entity framework to always use the named connection string and never anything else.
The reason this catches many developers out, and why it runs off an uses localdb is deceptively simple.
The Entity Framework DbContext by default will use the name of the data context derived class as a database name, and if it can't find a suitable connection string in any config file by that name, makes the assumption that your working in development mode without a full backing data store.
In my example above, EF would examine App and/or Web.config for a connection string called "myConnectionString"
Once it makes this development decision, it knows that localdb will be present as this gets installed with the latest builds of visual studio, and so it will automatically seek out a connection and populate it with a db that follows the name of the context in which it's used.
I've previously written a blog post on the subject, which you can find here :
http://www.codeguru.com/columns/dotnet/entity-framework-code-first-simplicity.htm
NOTE: The above applies to any database that you connect with using EF, it's the connection string that decides what/where the actual data store is.
Related
Visual studio creates a new database out of thin air to store my data. This is my DbContext:
public class LinkedDataContext : DbContext
{
public DbSet<LinkedData> LinkedData { get; set; }
}
No errors are being thrown, I just end up with another database that is only visible through the SQL Server Object Explorer unlike my initially created database which is the top one in the screenshot.
Edit
I migrated the whole accounts database generated by the MVC project to the MSSQL 2014 server. I simply added a database there and changed the connection string, then it automaticaly populated the database with the needed tables.
So I created my custom table, exactly as it was in the local database. I removed the local databases, the other connection strings and the Controller. Then I rebuild my project and created the controller again. But VS/MVC/EF or whomever is responsible is still creating a local database for my custom data.
When I create the controller it seems to find my table in MSSQL SERVER 2014, otherwise I would get a safe dialogue to store the sql file locally. So what is really happening here? Like I said, the account functionality worked instantly like a charm. My custom table in MSSQL simply won't get used.
EDIT
So I set the DefaultConnectionFactory in Web.config to my MSSQL SERVER 2014 and now it is generating a new Database inside my MSSQL SERVER. It seems to be the namespace, when I create a controller I need to pass in the namespace for the both the Model class and Context class.
Model class: LinkedData (DataVisualization.Models)
Data context class: LinkedDataContext (DataVisualization.Models)
The databases that keep getting generated automatically to hold my custom data are called: DataVisualization.Model.LinkedDataContext.
Does anyone have any idea what is really going on here?
I believe it is just the connection string in your Web.config. When you create a DbContext from an existing database outside of your project, Visual Studio prompts
The connection you selected uses a local data file that is not in the
current project. Would you like to copy the file to your project and
modify the connection?
If you select Yes, this copies the database file into your project, sets its Build Action to Content, sets a relative reference to it in your connection string and sets it to copy to your output directory on build.
If you modify the connectionString in your Web.config to point to the correct database you should be set (for future reference, answer No when asked if you want to copy it, unless that is really what you want to do - e.g. for a database file you're distributing with your binaries).
As an example, see the two connections listed below. You would see something like ProjectContext if you selected Yes, or something like ExternalContext if you selected No.
<connectionStrings>
<add name="ProjectContext" connectionString="data source=(LocalDB)\MSSQLLocalDB;attachdbfilename=|DataDirectory|\Database.mdf;integrated security=True;connect timeout=30;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
<add name="ExternalContext" connectionString="data source=(LocalDB)\MSSQLLocalDB;attachdbfilename=C:\Programming\.Net\DataVisualization\Data\DataVisualization\App_Data\Database.mdf;integrated security=True;connect timeout=30;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
</connectionStrings>
Note that the actual syntax of the connectionString may be different in your app depending on settings used, but the key part is the |DataDirectory| reference vs the correct path. The path is what you'd need to modify.
The shorthand solution is this:
public class LinkedDataContext : DbContext
{
public DbSet<LinkedData> LinkedData { get; set; }
public LinkedDataContext() : base("DefaultConnection")
{
}
}
I was assuming it would take the default connection if there was no connection named after the context. The reason was that I did not get a error so the connections would have been fine. Yet without specifying a connectionString in web.config it just seem to take part of the default string, since it does find my database and throws in it's namespace and creates a new database out of thin air. I might be new to MVC but I find this ridiculous default behavior. So I still have no clue what the idea behind this is.
Unless you want to have a couple of hundred connection strings for a fairly sized application the only way to go seems to be to call the parent constructor and specify the DefaultConnection there. Kind of ironic you have to "specify" default behavior.
Unlike what #tomtom told me, in almost 10 hours I did not find a single scenario that resembles mine. Maybe I was not clear but in my initial post I did specify each step I took. Using a MSSQL SERVER does not seem to be necessary.
Hope this helps someone else out.
STANDARD BEHAVIOR. As bad as it is. Your db template is copied to the runtime every time you hit the "debug" button, so you always start with a new datababase. Painfull as hell. Not sure how other's solve this - I never use this side of visual studio, I have a sql server installed and create my databases there manually. Makes sure i am always working against a defined copy. Obviously VS has no rights to create databases there ;)
If you bother using google or the site search a little you find tons of similar questions - this is a standard problem people regularly get trapped in because it is totally not what they expect.
(if you ask me, the whole db maintenance side of EF is broken anyway, including the "migrations" that hardly can use SQL Server most basic features).
I am currently developing a solution with both an ASP.NET project, and a WPF application. I have a common project too, with an ADO.NET entity model, where entities are generated from a database.
If i try to call anything from my database (MySQL) from my WPF, ASP or a Test project i get a InvalidOperationException where it says that no connection string named "DataModel" could be found in application config file.
I then have to add entity framework connectionstrings and other stuff to each project, in order to be able to fetch data from my common project or database. It also means if i want to change the db connection i have to do it in every single project. Isn't there a smarter way to do this?
Thanks..
Isn't there a smarter way to do this You're doing what most people do, at least for small and medium environments, by putting the connection string in each project.
Most projects need different connection strings for different environments (DEV, QA, PRODUCTION). I use and highly recommend the free add-in Slow Cheetah. That tool allows you to define XSLT transforms to modify XML files in your project. In this case, I use it to drop in the correct connection string depending on the build settings.
When you are ready to create a build for the PRODUCTION environment, you just change the Visual Studio solution configuration to Release, and the generated web.config/app.config contains the PRODUCTION connection string.
You can pass the connectionstring that has to be used to the constructor of your DbContext. You have 3 options to pass a connectionstring:
Pass nothing, EF will look for defaultconnectionstring in configfile, if none is found it will throw an error.
Pass the name of the connectionstring you want to use, if it's not found in the config file EF will use the default connectionstring.
public partial class MyDb : DbContext
{
public MyDb(string connectionStringName) : base(connectionStringName)
}
Pas a connectionstring to the constructor. EF won't look in any config files and just use that one, this is probably what you're looking for:
public partial class MyDb : DbContext
{
public MyDb(string connectionString) : base(connectionString)
//Or hardcode it in:
public MyDb() : base("datasource=...")
}
Edit: It is indeed not good practice to do the above, I'm just saying it's possible.
Setup - ASP.Net Web Application referencing a separate project which contains the dbml(soon to be edmx) and business logic classes.
I've been using Linq-To-SQL for a few years now and have been using the same setup as is described here for connection string passing from the web.config.
Can the provider connection string of Entity Framework be substituted with a DB connection string already defined in web.config?
So we have added another object context partial class and passed in the connection string using the constructors.
But this has the irritation of forcing me to manually delete the two constructors from the top of the dbml designer class every time it is rebuilt. We are moving to entity framework soon.
Is the same method recommended for EF? And do you still have to manually remove the two constructors on each rebuild?
http://www.connectionstrings.com/
You can find any specific connectionstring you want there. This is dependent on which type of database you are using, I can't explain further because I don't know which one you have.
I am trying to do this tutorial http://www.asp.net/mvc/tutorials/getting-started-with-aspnet-mvc3/getting-started-with-mvc3-part4-cs but instead of using the compact edition of SQL Server I am using a full install on my local machine. The way I read this tutorial is that the Entity Framework is suppose to create the tables from the objects I have defined. My problem is that I keep getting invalid object name dbo.movies, when I run the project. I finally got it to run by creating the table myself so I know the connection string and everything was correct.
My question is, is it possible to generate tables from objects created in C# and if so how?
is it possible to generate tables from objects created in C#?
Yes it is possible. Did you happen to create the Database manually in Management Studio before running the Code? That could be your problem. With Code First, the default convention is to create the database if it does not exist already. If the database already exists (even without the tables) then it is going to just use the existing database (but it won't try and create the tables).
You can either delete the database and try and run the code again to see if it will create it for you or put the following line in Global.asax:
Database.SetInitializer(new DropCreateDatabaseAlways<YourDbContextHere>());
Once it has run then I would suggest changing that line to:
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<YourDbContextHere>());
These namespaces are defined in System.Data.Entity
The DbContext class also exposes a Database property which defines the following useful methods:
Delete()
Create()
CreateIfNotExists()
So if you defined your class like so:
public class MyContext : DbContext {}
You can construct an instance like so:
MyContext db = new MyContext();
db.Database.Delete();
db.Database.Create();
ModelContext.Database.EnsureCreated();
If you create a Linq-to-Sql DataContext you can inject the structure directly into your Database whith:
DbDataContext db = new DbDataContext(connectionString);
db.CreateDatabase();
I don't know if this is kosher, but using code-first EF, when I use AddRange, EF will typically create all the tables I've defined. I wanted to keep the database because there are other tables I wanted to keep between application runs. I discovered that the tables would not be re-created after they were deleted if I did not also delete the table EF created called __MigrationHistory.
Once I deleted this table, then EF would re-create the tables without having to re-create the database.
This may not be an advisable approach in production, but for my development needs this resolved my issue. Maybe it will help someone else.
You can use FenixRepo library(also available as nuget package) to create particular table, that is a part of you Context. First of all, you should call one time, at startup static Initialize method, where first argument is a factory method, which returns instance of your Context and the second one is an instance of Configuration class. It will prepare SQL scripts for all of your tables, registered at your Context. At case of ASP.NET MVC it is a good decision to paste this code into Global.asax:
FenixRepositoryScriptExtractor.Initialize(() => new Context(), new Configuration());
Then you can create table of desired type MyTable this simple way:
var repo = new FenixRepositoryCreateTable<MyTable>();
//or repo = new FenixRepository<MyTable>();
repo.CreateTable();
Also, if your table spread between several migrations and they have nothing stuff corresponded to other tables, you can specify these migrations(i.e. names of classes from Migrations folder) via FenixAttribute, and exactly they will be used as source of SQL scripts, which will be used for table creation:
[Fenix(nameof(Initial), nameof(MyTableFirstMigration), nameof(MyTableSecondMigration))]
public class MyTable
{
//some stuff
}
Without this attribute, library will use default scripts. It is always better to specify migrations, because otherwise it is not guaranteed that all indexes will be created and also into your migrations you can include some custom code, that will not be executed at case of default solution.
Library is compatible and tested with EF 6.1.3 at case of MS SQL.
I am working with entity framework with code fist design pattern.
First of all I created two tables classes …
using System.Data.Entity;
public class CyclingClubContext:DbContext
{
public DbSet<CycleType> CycleType { get; set; }
public DbSet<CycleModel> CycleModel { get; set; }
}
When I run my project,
It create two tables at database which is auto-generated as CyclingClub.sdf file.
Then , I need to add another entity class. So, After I created new my entity class, I modify Context class like that …
using System.Data.Entity;
public class CyclingClubContext:DbContext
{
public DbSet<CycleType> CycleType { get; set; }
public DbSet<CycleModel> CycleModel { get; set; }
public DbSet<SideMenu> SideMenu { get; set; }
}
Then, I build my project, but it still show that build success message.
But when I run my project, problem start happen by showing message that
[InalidOperationException was unhandled by user code.]
The model backing the 'CyclingClubContext' context has changed since the database was created. Either manually delete/update the database, or call Database.SetInitializer with an IDatabaseInitializer instance. For example, the DropCreateDatabaseIfModelChanges strategy will automatically delete and recreate the database, and optionally seed it with new data.
So now I have more than one question.
1)How can I solve this error?
2)Whenever we need to add new entity class, do we need to delete existing database first and recreate the database as error message already suggest me?
3)If we need to delete first and recreate the new database , then I afraid that my existing record(s) will lose after recreate the new database. What will be the best solution?
4)Is SDF file really reliable one when we want to go enterprise level? If so let me know the reason why?
5)MDF file and SDF file , which one is better for enterprise level which need to deal with large volume of data and multiple users access at single time?
6)Is this possible to use MDF file in entity framework code first design pattern? If so let me know the reference links which showing how?
Every suggestion will be really appreciated.
The error exactly says how you should solve it. At start of your application you can set initializer of the database and control if it should be automatically recreated and when.
With current implementation EF code-first can only create whole database with all tables so indeed if you add new entities or modify existing entities EF can use them only if it deletes old database and recreate it. This will change in EF 4.3 which should contain EF Migrations. EF Migrations will offer incremental building of the database.
Yes. With currently available initializers your data will be lost. Initializers are currently more for development. You can derive custom initializer and override Seed method to fill your newly created database with some initial data.
SDF file is for SQL Server Compact edition. It is for very small databases. For example for local storage of WPF/WinForm application or as simple configuration database for web application. It is not for large data sets of intensive usage.
MDF file is for SQL Server. If you are going to build enterprise application working with large data sets you should go to full (commercial) edition of SQL server. SQL Express has limitations on CPU usage and database size for 2008 R2 is limited to 10GB (former versions has much worse limitation).
Yes it is possible. You just have to correctly define connection string for big SQL server and you must have permissions to create databases on that server.
You can think that my answers are not detailed enough but that is because you are asking too many questions in one thread.
Just follow this set of articles to learn about code first. It targets pre-release version but almost all content should be valid.