I'm working on a small project in WPF where you can insert, edit and search Recipes. I'm using Entity for this.
Recipe has a property, list<Ingredient>. When I insert an ingredient, it's OK, but when I insert a recipe with a list<Ingredient>, everything is ok except that in table recipe, there is no column ingredient at all. But in debug I clearly can see that in my method where I insert a recipe , the object recipe has ingredients count... I have spend couple hours trying different things out but with no luck.
This is how I insert (same as ingredient , where everything works)
public static void InsertRecipe(Recipe recipe)
{
RecipeDbContext ctx = new RecipeDbContext();
ctx.Recipes.Add(recipe);
ctx.SaveChanges();
}
Screen-shots from debug:
Recipe Table
Recipe object properties
Just for testing purposes , the ingredients should come from a listbox later on.
When I press ctrl property menu is fading away (reason why screen-shot is the way it is)
The whole User Instance and AttachDbFileName= approach is flawed - at best! When running your app in Visual Studio, it will be copying around the .mdf file (from your App_Data directory to the output directory - typically .\bin\debug - where you app runs) and most likely, your INSERT works just fine - but you're just looking at the wrong .mdf file in the end!
If you want to stick with this approach, then try putting a breakpoint on the myConnection.Close() call - and then inspect the .mdf file with SQL Server Mgmt Studio Express - I'm almost certain your data is there.
The real solution in my opinion would be to
install SQL Server Express (and you've already done that anyway)
install SQL Server Management Studio Express
create your database in SSMS Express, give it a logical name (e.g. RecipeDataBase)
connect to it using its logical database name (given when you create it on the server) - and don't mess around with physical database files and user instances. In that case, your connection string would be something like:
Data Source=.\\SQLEXPRESS;Database=RecipeDataBase;Integrated Security=True
and everything else is exactly the same as before...
Also see Aaron Bertrand's excellent blog post Bad habits to kick: using AttachDbFileName for more background info.
First, you must insert Recipe item and get the ID :
public static int InsertRecipe(Recipe recipe)
{
RecipeDbContext ctx = new RecipeDbContext();
ctx.Recipes.Add(recipe);
ctx.SaveChanges();
return recipe.recipeID;
}
And after that you can insert all Ingrédients, Something like that
public static void InsertIngredient(List<Ingredient> Ingredients, int recipeID)
{
IngredientDbContext ctx = new IngredientDbContext();
foreach (var ingredient in Ingredients)
{
Ingredient newItem = new Ingredient { IngredientID = ingredient.Ingredient,..., recipeID = recipeID};
ctx.Ingredient.Add(newItem);
}
ctx.SaveChanges();
}
Related
I tried many solutions found on Stackoverflow but none worked. I have a local database linked with EF Designer.
I'm using Entity Framework to create rows and store them into the database. It's working since database.SaveChanges(); returns 1 (not zero). Then I loop on the database rows and I can see that data were well saved.
Nonetheless, when I'm closing my console app and refreshing database, I can't find the values I just added and the rows I generated.
Working on this issue since few hours, browsed Internet but none of the answers helped me.
I already tried to do database.User.Attach() and EntityState.Modified but they didn't work.
I even tried to move my code in a different class, but it didn't work.
public static void AddClient(String firstName, String lastName, int phoneNumber, String email, String wishlist)
{
using (DatabaseEntity database = new DatabaseEntity())
{
database.User.Add(new User() {
First_Name = firstName,
Last_Name = lastName,
Phone_Number = phoneNumber,
Email = email,
Wishlist = wishlist
});
database.SaveChanges();
}
}
I expected data to be saved in the database after closing app, but they aren't.
I found the solution.
When Visual Studio uses local databases, at each debug it copies the databases and works on the copied.
So, I had to add a new connection on the Server Explorer that was targetting my_project_path/bin/debug/database.mdf
Then, I had to edit one of its properties which was Copy to Output Directory. Its new value is now Copy if Newer and now my datas are well saved in the database.
In a .NET Core project I have the following model:
public class WrapperContext : DbContext
{
public DbSet<WrappedFunction> Functions { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder builder)
{
builder.UseSqlite("Data Source=functions.db");
}
}
public class WrappedFunction
{
[Key]
public int FunctionId { get; set; }
public String FunctionName { get; set; }
public String AssemblyPath { get; set; }
public String FactoryName { get; set; }
}
As you can see it is an Sqlite database.
I have added the initial migration and updated the database. Before running my test application I have populated the Functions table with a single record. I can open the DB with SqliteManager to see the record is there.
I then try to access the DB with the following function:
static MUinfo getInfoFor(String command)
{
UFInfo rv = null;
using (var ctx = new WrapperContext()) // <---- record disappears here
{
foreach (var fn in ctx.Functions)
{
if (fn.FunctionName.Equals(command))
{
rv = new UFInfo()
{
AssemblyPath = fn.AssemblyPath,
FactoryName = fn.FactoryName,
CommandName = command
};
}
}
}
if (rv != null) return rv;
return "No Info for " + command;
}
However, when stepping through the debugger I see that the foreach loop never executes as there are no records in the DB. When I stop before executing the foreach I can verify (using SqliteManager) that my single record has been deleted from the database.
So, it would appear that the DbContext object is somehow deleting the data from the database. Why would that be and what have I done wrong here? I am fairly new to EntityFramework so I may have done something obvious, but it isn't obvious to me.
One additional bit of info here. The project that does the db access is a library project. I have to copy the DB over to the build directory of the application before populating it and running the application. I don't know if that makes a difference or not.
Edit 6/19/17 (18:51):
OK. A bit more information (thanks to #StevePy). Nunit3 seems to conflict with EFCore (though I don't get any errors on restore) so I couldn't create a unit test for this. So I inserted a using (var ctx...) above the one in the listing above and inserted a couple of dummy records. Then I exited that using block and when I entered the one to traverse the records they were there.
However, I then commented out the dummy insertions and reran my test. And, once again, both records disappeared. So there is something very weird going on here with EFCore.
Edit 6/20/17 (15:30):
Well, I'm still not sure what is going on but there is an odd interaction between EFCore and Microsoft.Data.Sqlite.
I decided to remove all references to EFCore and simply use SQL queries on the DB. I did this without recreating the DB (so I was using the one already created by EFCore). I noticed the exact same behavior when I created a new SqliteConnection without using EFCore.
In desperation I deleted the DB and recreated it from scratch using Microsoft.Data.Sqlite. This DB didn't have any of the EFCore information in it, obviously. I then populated the DB with some test records and went to use it. No more disappearing records.
Apparently there was something very strange in the way EFCore set up the database in the first place that caused the issue. But I don't have any idea what it was.
What is likely happening is that you are using CodeFirst /w EF, but taking a DB first approach when it comes to testing your new code. EF tracks schema changes within the database and my guess is that by you creating the table ahead of time it does not know that the schema is vetted, so it drops and recreates it on context start-up.
The fix here should be to create a "stub" test that populates a test record one time using your EF model. From there you should have a table that EF recognizes against that context and accepts. From there you can create test records in whatever editor for testing purposes.
SQLite has several limitations when it comes to schema migration that you probably will want to consider as well. (see: https://learn.microsoft.com/en-us/ef/core/providers/sqlite/limitations)
You might be better off setting up DB first, telling EF how to map to an existing SQLite schema rather than trying to use Code-First as migration is pretty limited for that DB engine.
I'm adding new lines to a database for our company's "order list" for each order created, using the firebird ado.net client. The code i've written works fine for listing items, but inserting new ones doesn't appear elsewhere (e.g. in flamerobin). What I think is happening is that the transaction isn't being committed, seeing as it's recognised within my code (can't add duplicate values).
Code:
using (FbConnection fbCon = new FbConnection)
{
fbCon.Open();
***command w/ parameterised command string***
using (FbTransaction fbTrans = fbCon.BeginTransaction())
using FbCommand orderCommand = new FbCommand(cmdString, fbCon, fbTrans)
{
***Adding parameters and values***
try
{
int recordsAffected = orderCommand.ExecuteNonQuery();
fbTrans.Commit();
}
catch (FbException E)
{
fbTrans.Rollback();
fbCon.Close();
throw E
}
}
recordsAffected returns 1 but I am not able to see the updated values in flamerobin or the db management program. Am i missing something?
If anyone else runs into this problem, it's in Visual Studio's debugging settings. https://visualstudiomagazine.com/blogs/tool-tracker/2012/05/dealing-with-local-databases-or-why-your-updates-dont-stick.aspx explains pretty clearly, but basically VS makes a copy of your database in bin/Debug of your project (Ostensibly to not mess with your data) but if you actually need to use/view the data externally, either link your external application to the debug database (e.g. flamerobin). You may also need to set your project database settings to Copy if Newer if you want your updates to stay, as the default setting copies the database into the folder each time you run your c# app.
I am using VS2010 , and I am building a simple wpf application using C#
I have built a database using SQL Server 2008
in my application I created a LINQ to SQL class and created a dbml file
then I created a datacontect and did everything right
BUT
when I can't aaccess my database file everytime I try to , I mean when I insert anew row in my datacontexct I can check it and see it but when I look in my mdf file I can't find anything
I think that my datacontexct must be connected to my database file somehow
please help me because I seriously need it
The connection string, that is passed to the datacontext, references the MDF.
// Northwnd inherits from System.Data.Linq.DataContext.
Northwnd nw = new Northwnd(#"northwnd.mdf");
var cityNameQuery =
from cust in nw.Customers
where cust.City.Contains("London")
select cust;
foreach (var customer in cityNameQuery)
{
if (customer.City == "London")
{
customer.City = "London - Metro";
}
}
// you must call this this commit the changes
nw.SubmitChanges();
Call .SubmitChanges() on your DataContext after adding an item.
Okay, this is really weird. I made a simple database with a single table, Customer, which has a single column, Name. From the database I auto-generated an ADO.NET Entity Data Model, and I'm trying to add a new Customer to it like so:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Test
{
class Program
{
static void Main()
{
Database1Entities db = new Database1Entities();
Customer c = new Customer();
c.Name = "Harry";
db.AddToCustomer(c);
db.SaveChanges();
}
}
}
But it doesn't persist Customer "Harry" to the database! I've been scratching my head for a while now wondering why such a simple operation doesn't work. What on earth could be the problem!?
EF requires that you have a unique index for many operations.
Try adding an identity field (primary key) to your table. Delete and recreate your model and try again.
Edit:
It looks like you are running this from a console app.
Do you have a connection string in the app.config file?
Do you have more than one project in your solution?
Are you getting any exceptions?
Edit2:
Next things to try:
Use SQL Server profiler to see what is being sent to the database
Open the EF model in an editor to see the xml, check if there are any errors
Place db in a using statement to ensure the connection/transaction is closed cleanly before process exit.
OK, here's a longshot. Are you sure your connection string is pointing to the right place? And the connection is functioning?
You can verify it by using SQL Server Management Studio to add some records to your test database, and then do something like
foreach (Customer c in db.Customers)
{
Console.WriteLine(c.Name);
}
Make sure that the "Copy to Output Directory" property of the database file is not set to "Copy always." If it is, every time you rebuild the application, the database may be clobbered with a pristine copy.
See: Entity Framework not flushing data to the database