Entity Framework isn't saving data to database in WPF - c#

I'm developing a POS in WPF.
For CRUD operations, I'm using Entity Framework.
Created a WPF View ProductADD
Product Add View Snap
Created a Class ProductController in Controller Folder
Made object of Entity Framework in ProductController Class ProductController Calss Snap
Created a method: SaveProduct(Product product) which is taking product object as argument and saving it to database using EF.
And From Xaml.Cs I'm calling ProductController Class's Saveproduct method and sending the new product data to it.
private void Button_Click(object sender, RoutedEventArgs e)
{
ProductController pc = new ProductController();
PRODUCT product = new PRODUCT();
product.PRODUCT_NAME = Product_Name.Text.ToString();
product.UNITPRICE = Convert.ToInt32(Unit_Price.Text.ToString());
product.CATEGORY_Id = 1;
pc.SaveProduct(product);
MessageBox.Show("Product Added Successfully");
this.Close();
}
And in ProductController the following code is updating the database
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PizzaLounge.Models;
namespace PizzaLounge.Controllers
{
public class ProductController
{
PizzaLoungeEntities db = new PizzaLoungeEntities();
public void SaveProduct(PRODUCT product)
{
db.PRODUCTs.Add(product);
db.SaveChanges();
}
}
}
The code executes successfully but it doesn't save the product in database. P.S. I have used db.savechanges().
Am I missing something or using wrong approach to update database?

You are probably using |DataDirectory| in your connection string. If debugging in Visual Studio, the database you are using is in the bin/debug folder.
Unfortunately if you look at the db through Server Explorer it has a different connection string so you don't see the changes.
Also if the database property "Copy to Output directory" is set to Copy Always then every time you debug you will overwrite your db and you won't see the data you added. You can check if this is happening by using a new db context in the same debug session where you add the records. If the new context can get the records from the db then you know they must be being written (as well as the other checks listed in the comments)
This can be fixed by changing Copy To Output Directory to Never Copy or Copy If Newer.

Because you are using mdf file attached to your project so your problem is like this question
Attaching database to my project
You are saving data to database that is in bin\debug folders ,and then you see the mdf file that is in your project folder and you don't see the data .
change your connection string from DataDirectory to
absolute path to the project database file. When deploying, just change it back to |DataDirectory|

How did you checked that the products haven't been added, from db.PRODUCTs or from the Database Explorer?
Maybe you just need to dispose your context, change your ProductController for something like:
using(var db = new PizzaLoungeEntities()){
db.PRODUCTs.Add(product);
db.SaveChanges();
}
Or to dispose ProductController after you finish to use it.

Related

Why DataAdapter.Update() does not update the database

There is a DataGridView in my form, and I have a save button. Both the DataAdapter and the DataSet are automatically generated.
I want to use DataAdapter.Update() to update my database, but it seems nothing changed after I updated the DataGridView when I open the table in .mdf or generate the solution again.
I knew this was asked and read some posts, trying to find the solutions but it doesn't work.
I have set the .mdf file property 'Copy to output directory' to 'Copy if newer'
BindingSource and BindingNavigator work successfully.
Code Sample
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.myTableTableAdapter.Fill(this.myDatabaseDataSet.myTable);
SqlCommandBuilder sqlCommandBuilder = new SqlCommandBuilder(myTableTableAdapter.Adapter);
myTableTableAdapter.Adapter.InsertCommand = sqlCommandBuilder.GetInsertCommand();
myTableTableAdapter.Adapter.DeleteCommand = sqlCommandBuilder.GetDeleteCommand();
myTableTableAdapter.Adapter.UpdateCommand = sqlCommandBuilder.GetUpdateCommand();
}
private void SaveSToolStripButton_Click(object sender, EventArgs e)
{
try
{
bindingSource1.EndEdit();
myTableTableAdapter.Adapter.Update(myDatabaseDataSet.myTable);
MessageBox.Show("Succeed");
}
catch (Exception err)
{
MessageBox.Show(err.Message, "Failed");
}
}
}
}
Just solved this problem. Someone with the same problem may refer to this.
Why saving changes to a database fails? Steve's answer is quite helpful to understand this problem.
I did modify my database, but when I connect the datasource, it just copy again, so it seems the update fails.
You can write the connection manually, changing the |Directory| to where your database actually is. Or do something like this:
string dataDir = AppDomain.CurrentDomain.BaseDirectory;
if (dataDir.EndsWith(#"\bin\Debug\")
|| dataDir.EndsWith(#"\bin\Release\"))
{
dataDir = System.IO.Directory.GetParent(dataDir).Parent.Parent.FullName;
AppDomain.CurrentDomain.SetData("DataDirectory", dataDir);
}
But I don't recommend this because it may modify your original database when you're debugging. It should be only modifying my database in the bin folder while keeping the original database intact.
What you have to do is just setting your .mdf file Copy to directory property to Copy if newer or Copy Never (In this case, add a script to copy the file to the bin\debug folder only if it doesn't exist). And do not focus too much on your original .mdf in your Resource Manager.
And other notes:
Lines like myTableTableAdapter.Adapter.UpdateCommand = sqlCommandBuilder.GetUpdateCommand(); are not necessary.
When associated with a DataAdapter, the DbCommandBuilder automatically generates the InsertCommand, UpdateCommand, and DeleteCommand properties of the DataAdapter if they are null references. If a Command already exists for a property, the existing Command is used.
MSDN
I need to check before calling BindingSource.EndEdit()
this.Validate();

'file is not a database' or 'No migrations were applied. The database is already up to date.' when creating Database.sqlite in non-default path

I am an extremely novice C# programmer following a series of video tutorials using Discord.net and sqlite to create a bot for my server to add various commands and automate various tasks.
Everything has gone fine in the tutorial until I reached the sixth installment, https://www.youtube.com/watch?v=-Lf6w7WZvT0. A little after 12:30, the author attempts to use update-database in the Package Manager Console to create a database named Database.sqlite at a non-default location. However, attempting to create this database the way he has it written results in an error, SQLite Error 26: 'file is not a database'.
The tutorial author's solution is to create the database at the default location, manually move it to the preferred location, then edit the code to use the preferred location. To me this seems inelegant and I'd like to figure out how to make the Package Manager Console create the progam in the correct location.
Here is the program as the tutorial author originally writes it
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
namespace MyBot.Resources.Database
{
public class SqliteDbContext : DbContext
{
public DbSet<Stone> Stones { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder Options)
{
string DbLocation = string DbLocation = Assembly.GetEntryAssembly().Location.Replace(#"bin\Debug\netcoreapp2.1",
#"Data\Database.sqlite");
Options.UseSqlite("Data Source=" + DbLocation);
}
}
}
This results in the file is not a database error.
He then changes this to
string DbLocation = string DbLocation = Assembly.GetEntryAssembly().Location.Replace(#"bin\Debug\netcoreapp2.1",
#"Data\Database.sqlite");
Options.UseSqlite("Data Source=Database.sqlite"_;
This creates a Database.sqlite file in the MyBot directory, which the author then moves to the MyBot\Data directory. He then changes the program to
string DbLocation = string DbLocation = Assembly.GetEntryAssembly().Location.Replace(#"bin\Debug\netcoreapp2.1",
#"Data\");
Options.UseSqlite($"Data Source={DbLocation}Database.sqlite";
And from there the program runs as expected.
I deleted the Database.sqlite file and reran the code as it is above to see what happens, and got the message No migrations were applied. The database is already up to date.
Rerunning the various steps leads to the same result each time.
I've attempted to google for the two error messages and haven't found anything useful. I also checked the api page for DbContextOptionsBuilder at https://learn.microsoft.com/en-us/ef/core/api/microsoft.entityframeworkcore.dbcontextoptionsbuilder and couldn't find anything that would indicate why it wasn't working.
Any help getting the Database.sqlite file to write to MyBot\Data would be much appreciated.

C# adding table object to entity and saving changes not working

I'm learning about ADO.Net entity framework, and
I'm stuck at adding entity table object to the database.
I have a local database in solution called testDB.
It has two columns - id(primary, unique, identiy),name(varchar(100))
and entity for it. The main application code is here below.
Problem is, that using this code it doesn't add anything to the table, but also
I'm not having any errors.
What could go wrong?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace entityproject
{
class Program
{
static void Main(string[] args)
{
String someString;
someString = "Just a test";
testDBEntities tdbEntity = new testDBEntities();
test tblTest = new test();
tblTest.name = someString;
tdbEntity.test.Add(tblTest);
tdbEntity.SaveChanges();
}
}
}
App.config here
http://pastie.org/6980938
I think I know the problem - had the same thing last time I tried using SQL CE.
The connection string doesn't point to the sdf file that you created - it uses a new one that I believe gets put into your bin\Debug or bin\Release directory (in your config file as data source=|DataDirectory|\testDB.sdf), with your EXE and DLLs. If you check that directory, I bet you'll find another sdf file there, that has a bunch of records added.
If you want to use the sdf that you've already created, change the connection string to point specifically to that file.

accessing a dataset and table adapter from a new class

I created a working Windows Forms project in C# that accesses an Access database of recipes. Using table adapters and the dataset I am able to query, update and insert new data into the database.
I created a new VS project, imported my database and started a new class. My problem is when I try to set up the table adapters I get errors, specifically with the .Fill() method. When I check the datasource.xsd I can see that the .get() and .Fill() methods were created but I can't seem to access them like I did when I just dragged and dropped the binding source onto the WinForm previously.
I copied the code to programmatically create the table adapters from the MSDN website but I get the error on the line where I call ingredientTableAdapter.Fill(recipiesNewDataSet); method. Any one have a clue why? Here's my code on this project so far:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyRecipeDataBase
{
class QueryClass
{
recipiesNewDataSet recipiesNewDataSet = new recipiesNewDataSet();
recipiesNewDataSetTableAdapters.IngredientTableAdapter ingredientTableAdapter = new recipiesNewDataSetTableAdapters.IngredientTableAdapter();
ingredientTableAdapter.Fill(recipiesNewDataSet);
}
}
The answer was staring me in the face!
You're putting code directly in the class body. It should be inside a function. Inside the class constructor, for instance.
class QueryClass
{
public QueryClass()
{
recipiesNewDataSet recipiesNewDataSet = new recipiesNewDataSet();
recipiesNewDataSetTableAdapters.IngredientTableAdapter ingredientTableAdapter = new recipiesNewDataSetTableAdapters.IngredientTableAdapter();
ingredientTableAdapter.Fill(recipiesNewDataSet);
}
}

C# reference to a dll file i created doesn't work as it should

i'm using microsoft visual C# 2010 express to write a form program to read and write to an access database.
i created a class that is designed to read/write to the database file, saved it under a namespace and created a dll from it.
it is set as ".net Framework 4"
in my main program i added the reference to the dll file but when i try to add it to the code with
using Database;
it won't work even that the Database is in the reference of the namespace.
am i doing something wrong? or is there another way to use the commands from Database in my main program other then copying it to it?
// update //
solved
added public to all database public and DataBase db = new DataBase();
DATABASE.cs is use it for dll
using System;
using System.Collections.Generic;
using System.Data.OleDb;
namespace Database
{
public class DataBase
{
public DataBase()
{
}
public void ItemInsert(string name,string creator,string publishing,string itemType,string genere, string year)
the main program
using System;
using System.Windows.Forms;
using Database;
namespace library
{
public partial class newItemForm : Form
{
private void btnConfirmNewItemClick(object sender, EventArgs e)
{
DataBase db = new DataBase(); //this solved it
db.ItemInsert(txtItemNameType.Text, txtEditorType.Text, txtCreatorType.Text, comboBoxType.Text, txtGenereType.Text, txtYearType.Text);
}
}
}
You also need to Add a Reference to said assembly in your current project. The using statement brings a referenced assembly into scope...
right click you project in visual studio, select add refrence then choose Browse tab, then find the poject folder and get in bin -> debug and then you will see the dll choose it. visual studio will add it to your refrences, now you need to add a using on top of the pages you want it like this:
using mydllName;
if you didnt find your dll:
Load the librery project agian and right click in visual studio and press Build it will generate the dll.
You must add a reference to the assembly you created. The point of creating an Assembly is not that you don't have to "copy it" to another project, but rather that you don't have to duplicate code.

Categories

Resources