I am trying to create a DB using EF code first.
I did the following:
Created the classes
Created a data context using said classes
I used parameterless constructor on context class with :base("connectionstring")
I opened the Nuget Manager console and i typed the commands:
enable-migrations
add-migrations mydatabase
update-database
After doing this the folder with the migration files appeared in the solution explorer but the Database still doesn't appear in my SQL Server Management Studio
Below is the code:
1.Classes
public class Kid
{
public int KidId { get; set; }
public int Age { get; set; }
public string Name { get; set; }
}
[Table("School")]
public class School
{
[Key]
public int SchoolId { get; set; }
public string SchoolName { get; set; }
public List<Kid> Kids { get; set; }
}
public class SchoolContext:DbContext
{
public SchoolContext() : base("SchoolContext") { }
public DbSet<Kid> Kid { get; set; }
public DbSet<School> School { get; set; }
}
2.Main
class Program
{
static void Main(string[] args)
{
SchoolContext myDb = new SchoolContext();
Kid mykid = new Kid { Age = 14, KidId = 2, Name = "Adrian" };
Kid mykid2 = new Kid { Age = 16, KidId = 3, Name = "Adriansan" };
School mySchool = new School { Kids = new List<Kid>{ mykid, mykid2 }, SchoolId = 73, SchoolName = "Iovan Ducici" };
myDb.Kid.Add(mykid);
myDb.School.Add(mySchool);
myDb.SaveChanges();
Console.ReadLine();
}
}
I suspect there's something to be done in the App.config file which has a connectionString tag which is empty but I don't know what it has to be completed.
Generally you need to have a connection string in the app config that knows 'where' is your database created at. A context is just a blueprint to create the database that 'SchoolContext' should be referencing a connection string in an app config or similar to an actual project that runs the EF Code First
<connectionStrings>
<add name="SchoolContext" providerName="System.Data.SqlClient" connectionString="Server=.;Database=SchoolContext;Integrated Security=True;"/>
</connectionStrings>
If you do not have this it will most likely not work. And since you do a lot of stuff manually with EF code first it may not show up. Or it may assume an MS default database which handles connections differently than MS SQL or it may be SQL Express.
I took this tutorial from this site a while back and it is fantastic for learning the ins and outs of the basics for EF Code First: http://www.entityframeworktutorial.net/code-first/entity-framework-code-first.aspx
Related
I am trying to learn asp.net mvc by doing hands-on. So i started with very small web application using asp.net mvc along with entity framework to access sql server.
I created one table in sql server localdb
USE Ourlifestory ;
GO
create table staticlocations(
LocationID int primary key,
LocationName varchar(30),
Tripdate datetime,
Locationimage image)
Below is the connection string
<add name="OurLifeStoryDBContext" providerName="System.Data.SqlClient" connectionString="Data Source=(LocalDB)\v11.0; Initial Catalog=Ourlifesotry; Integrated Security=True;" />
DBContext class :
public class OurLifeStoryDBContext : DbContext
{
public OurLifeStoryDBContext()
: base("name=OurLifeStoryDBContext")
{
}
public DbSet<StaticLocations> Location { get; set; }
}
Model class for one table :
[Table("staticlocations")]
public class StaticLocations
{
[Key]
[Column(Order = 1)]
public int LocationID { get; set; }
[Column(Order = 2)]
public string LocationName { get; set; }
[Column(Order = 3)]
public DateTime Tripdate { get; set; }
//[Column(TypeName="image")]
//public byte[] LocationImage { get; set; }
}
Controller action method accessing this dbcontext :
public ActionResult GetLocationDetails(int locationID)
{
var dbContext = new OurLifeStoryDBContext();
var location = dbContext.Location.ToList();
return View("_GetLocationDetails");
}
But in above action method on the below line ,
var location = dbContext.Location.ToList();
i am getting zero records though i am very i have one record which i manually inserted through insert statement in database.
Any thoughts what i am missing here?
Here is why nothing was returned, there was a typo in your connection string:
Initial Catalog=Ourlifesotry;
in your connection string should be
Initial Catalog=Ourlifestory;
Why did it not give any "error" or indication?
That's because Entity Framework cannot detect if you spelled your database name wrong. For all it knows, your database could be called "misssssspelled".
Also, when there is no existing database with the provided name, instead of an error value/warning, it will simply return nothing instead.
I have a C# app which connects to a Web API which feeds my app some XML data for estate agency listings and agents.
The XML looks something along these lines:
<Snapshot>
<Agents>
<Agent id="838388" firstName="John" surname="Smith"/>
<Agent id="838389" firstName="Jane" surname="Doe"/>
<Agent id="838390" firstName="Mary" surname="Appleton"/>
<Agent id="838391" firstName="Peter" surname="Gill"/>
</Agents>
<Listings>
<Listing id="1737672" officeId="801948" agencyName="Century 21">
<Agents>
<AgentRef id="838388" />
<AgentRef id="838391" />
</Agents>
</Listing>
<Listing id="1737673" officeId="801949" agencyName="Remax">
<Agents>
<AgentRef id="838390" />
<AgentRef id="838389" />
</Agents>
</Listing>
</Listings>
</Snapshot>
I have decided to use using Entity Framework 6.2, code-first approach. So I created these two classes:
public class Agent
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int AgentId { get; set; }
public string FirstName { get; set; }
public string Surname { get; set; }
public virtual ICollection<Listing> Listings { get; set; }
}
and
public class Listing
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ListingId { get; set; }
public int OfficeId { get; set; }
public int AgencyName { get; set; }
public virtual ICollection<Agent> Agents { get; set; }
}
As you can see, it's a many-to-many relationship between Agents and Listings. So one Agent can have zero or more listings associated to him, and one listing can have zero or more agents associated to it.
So, my app reads all the agents in the first tag, and inserts all the agents into the agents table. Then, later, when it reads all the listings, it looks like EF is trying to create those agents again. Obviously, this gives a PRIMARY KEY violation error, as it's trying to add a second agent again with the same ID.
I am using XDocument to parse the XML. This is the bit where I read the AgentRef elements of the listing:
XElement root = xDoc.Root.Elements("Listings").Descendants("Listing");
if (root.Descendants("Agents").Any())
{
List<string> agentRefs = root.Element("Agents").Elements("AgentRef")
.Select(a => a.Attribute("id").Value).ToList();
listing.AgentRefs = agentRefs.Select(int.Parse).ToList();
}
Any ideas how I can tackle this?
If the agent already exists in the DB you must EF tell that by attaching the agent to the context:
using(var myContext = new MyContext)
{
var agent = new Agent() { AgentId = 838388 };
myContext.Agents.Attach(agent);
var listing = new Listing() { ... };
listing.Agents.Add(agent);
myContext.Listings.AddObject(listing);
myContext.SaveChanges();
}
I'm currently creating a Windows Forms Application. I require a local database and have opted to use the code-first approach with the Entity Framework in order to build it. I have not worked with a database with C# before and I am struggling to set one up with the entity framework.
I currently have two classes: Ingredient, and Recipe. Both contain POCOs. From what I can gather, the entity framework should create a local database, making these classes tables. However a database is not being created.
Could anyone shed some light on what I am doing wrong? I apologise if my question is too broad.
Thank you for your time.
Ingredient Class:
public class Ingredient
{
public int IngredientID { get; set; }
public string IngredientName { get; set; }
public string IngredientDescription { get; set; }
public virtual Recipe Recipe { get; set; }
}
Recipe Class:
public class Recipe
{
public int RecipeID { get; set; }
public string RecipeName { get; set; }
public string RecpeDescription { get; set; }
public virtual List<Ingredient> Ingredients { get; set; }
public Recipe()
{
this.Ingredients = new List<Ingredient>();
}
}
DbContext Class
class RecipeContext : DbContext
{
public DbSet<Recipe> Recipes { get; set; }
public DbSet<Ingredient> Ingredients { get; set; }
}
EF is quite flexible with these things. Get acquainted with the Nuget Package Manager Console (it is from there that you'll interact with Entity Framework DB generation routines). Following these steps you should be good to go:
Add a connection string to your start up application. An example is the following:
<configuration>
<connectionStrings>
<add name="Local"
connectionString=
"Data Source=.;Initial Catalog=NAME;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
Create a Context class that inherits DbContex;
Add the following constructor to you Context class:
public Context() : base("Local") {}
Add DbSet properties to your Context class (so EF can track them down);
Go to the Package Manager Console, select the project that holds the DbContext class, and type the following:
Enable-Migrations
On the same console type:
Add-Migration Initial
Again in the same console:
Update-Database
This should create a database with the name you have set in the connection string.
Hope this helps!
Cheers!
You need a connection string and one of database initializers that create a database if it doesn't exists.
public class RecipeContext : DbContext
{
// the default constructor
public RecipeContext() : base() { }
// this one lets you pass a connection string
public RecipeContext( string connectionString ) : base( connectionString ) { }
...
Then, at the very beginning of your app set the initializer:
Database.SetInitializer<RecipeContext>(new CreateDatabaseIfNotExists<RecipeContext>());
And finally, just try to connect to your database, with a valid connection string:
// local database connection string has to point to the local db server
string cs = "server=(localdb)/v11.0;database=anewdatabase;integrated security=true";
using ( var ctx = new RecipeContext( cs ) )
{
// any database operation will first trigger the initializer
// which initializes the database once per app domain
// in case of the CreateDatabaseIfNotExists
// a new, empty database matching your model is created
}
I'm just new to Entity Framework and I currently practicing on Codefirst to generate my models. One confusion I have was that, when I'm calling the DbContext to create the whole schema it would need me to insert data first to any of the tables before all of them will be created. Does this make sense? Or maybe I've just done something wrong with my codes. Thanks?
Here's a sample code:
Model
public class Employee
{
public int EmployeeID { get; set; }
public string Firstname { get; set; }
public string Middlename { get; set; }
public string Lastname { get; set; }
}
Here's my DBContext:
public class MyContext : DBContext
{
public MyContext():base(#"
Data Source=(localdb)\v11.0;
AttachDbFilename=c:\users\nsutgio\MyDB.mdb;
Initial Catalog=MyDB;
Integrated Security=true;
Connection Timeout=30")
{
}
// I override onModelCreating here...
public DbSet<Employee> Employee { get; set; }
}
Load the database...
private void loadDB()
{
using(MyDBContext ctx = new MyDBContext())
{
// The commented code here is the one I've said, If I'll comment out this code below
// the database will not be created. My question is do we really need to insert data
//first before the whole database will be created?
//Employee _ee = new Employee();
//_ee.Firstname = "nsutgio";
//ctx.Employee.Add(_ee);
ctx.SaveChanges();
}
}
You could manage that process. But by default db recreates each time when data model changing during application start.
If you interested deeply in that process read this article
One day ago I started using Entity Framework CodeFirst in simple Windows Forms project (C#). I created two models:
[Table("SavesSet")]
public partial class Saves
{
public Saves()
{
this.SkillsSet = new HashSet<Skills>();
}
[Key]
public int SaveID { get; set; }
public string Player { get; set; }
public int Age { get; set; }
public int Money { get; set; }
public virtual ICollection<Skills> SkillsSet { get; set; }
}
[Table("SkillsSet")]
public partial class Skills
{
[Key]
public int SkillID { get; set; }
public string Name { get; set; }
public int Value { get; set; }
public int SavesSaveID { get; set; }
public virtual Saves SavesSet { get; set; }
}
Then I added one row into my database using Visual Studio Database Explorer (local database using SqlServerCe 3.5):
SaveID = 1
Player = "TEST"
Age = 1
Money = 1
I also created form with ListView and wrote some code:
private SavesContext db = new SavesContext();
foreach (Saves s in db.SavesSet.ToList())
{
ListViewItem l = new ListViewItem();
l.Name = s.SaveID.ToString();
l.Text = s.Player;
ListViewSaves.Items.Add(l);
}
But when I started program debugging ListView was empty. I set breakpoint, viewed local variables and saw that SavesSet count was 0.
I added one row via code:
Saves s = new Saves();
s.Player = "TestName";
s.Age = 5110;
s.Money = 200;
db.SavesSet.Add(s);
db.SaveChanges();
And ListView displayed this one. But in my database there was nothing (and its size didn't change). I restarted Visual Studio - and my trouble was still actual: ListView shows item, but database was empty. I checked ConnectionString in App.Config and in VS Database Explorer - they were equal.
So, my question is: How can I explore my real database and where does it stores?
Update.
My DbContext:
public SavesContext()
: base("Saves")
{
}
public DbSet<Saves> SavesSet { get; set; }
public DbSet<Skills> SkillsSet { get; set; }
And my App.Config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
</configSections>
<connectionStrings>
<add name="TextSim.Properties.Settings.Saves" connectionString="Data
Source=C:\Documents and Settings\My\My Documents\visual studio
2010\Projects\TextSim\TextSim\Saves.sdf"
providerName="System.Data.SqlServerCe.3.5" />
</connectionStrings>
</configuration>
Entity Framework uses something called Convention over configuration, which means that if you don't supply values for certain things, it uses default values.
If you do not specify your connection string, it will use a default connection string derived from your EF's Namespace and DbContext name. If this is the case, then it would create a new (blank) database using the default system and not use the one you may have configured in Web.Config.
Thus, when you save things, it does save, just to the wrong database.