Entity Framework insert doesn't work - c#

I have a very simple windows form project with Entity Framework.
Simply I draged my tables from "Data Source" tab in my "form" and it generate for me a "DataGridView" and a "BindingSource".
Data bound successfully and when I run project I can see "DataGridView" filled with data correctly and I can update any cells value from "DataGridView".
Problem is I can not insert any rows in my "DataGridView".
Here is some codes that I wrote hope it be useful to solve problem:
Teachers_DBEntities context = new Teachers_DBEntities();
private void SaveItem_Click(object sender, EventArgs e)
{
context.SaveChanges();
MessageBox.Show("saved successfully");
}
private void Form1_Load(object sender, EventArgs e)
{
teachers_tableBindingSource.DataSource = context.teachers_table.ToList();
}
Upates for comments
I tested my "BindingSource" and found that it successfully understand if new record insert in "DataGridVeiw", but changes won't apply in database when I call context.savechanges();
context.savechanges() works fine when I update a cell, but it doesn't work when I try to insert a new record in my "DataGridView".
In my edmx file I mapped all columns correctly and primary key StoreGeneretedPattern property is set to Identity and its Entity Key property is set to true. Its auto-increment property in my SQL Server database file is set to true.
any help is appreciated.

context.savechanges() works fine when I update a cell, but it doesn't work when I try to insert a new record in my "DataGridView".
What do you mean by "it doesn't work"? New record does not appear in database? Of course it won't.
In this line
teachers_tableBindingSource.DataSource = context.teachers_table.ToList();
you're breaking DataSource's connection to context. Any new item inserted into it will be inserted not into teachers_table, but into List you created over it.

using (var context = new YourEntities ())
{
var dpt = new yourObject { Name = "Test" };
context.yourObject.Add(dpt);
context.SaveChanges();
}
you are missing to add object in the context

In .Net 4.5 I get this error when I remove ToList():
Data binding to a store query is not supported.
Instead populate a DbSet with data, for example by calling Load on the DbSet, and then bind to local data.

I had exactly this same problem. And after a lot of hours, I just finally found myself the solution...
I'm using C#, .Net Framework, Entity Framework 6.4
If I set
teachers_tableBindingSource.DataSource = context.teachers_table.ToList();
data is updated in DB but not inserted.
If I set (as suggested)
teachers_tableBindingSource.DataSource = context.teachers_table;
I get the error:
System.NotSupportedException HResult=0x80131515 Mensaje = Data
binding directly to a store query (DbSet, DbQuery, DbSqlQuery,
DbRawSqlQuery) is not supported. Instead populate a DbSet with data,
for example by calling Load on the DbSet, and then bind to local data.
For WPF bind to DbSet.Local. For WinForms bind to
DbSet.Local.ToBindingList(). For ASP.NET WebForms you can bind to the
result of calling ToList() on the query or use Model Binding, for more
information see http://go.microsoft.com/fwlink/?LinkId=389592.
Finally I got the answer tnanks to that hint:
context.teachers_table.Load(); //Load records in this DataSet<>
teachers_tableBindingSource.DataSource = context.teachers_table.Local.ToBindigngList();
Now it works. Data is deleted, inserted and updated properly in database.

Related

Database First with Windows Form

Hi I have a windows Form Application and using Database First Approach. When I am trying to save data using following code its not showing any error but not saving data into my .mdf database.
Models.NorthwoodRetreatsDBEntities db = new Models.NorthwoodRetreatsDBEntities();
db.Treatments.Add(new Models.Treatment() {
Name=_name,
address=_address,
phone=_phoneNo,
Email=_emailAddress
});
db.SaveChanges();
Not showing error I am also trying see is it inserted using the following line of code
bool a = db.ChangeTracker.HasChanges(); //double check if there was any change detected by EF or not?
it is returning true and
int UserID = db.Treatments.Max(item => item.AccommodationID);
Always returning 1 but when I explore database table showing nothing there and also when I am adding second item "int UserID" again 1. Now I am just wondering that can I use Database First EF with Windows Form. Could you please advice.

Updating Local Database with Entity Framework

I have a problem regarding updating local database with Entity framework.
I'll show you just small basic example of a problem, and I will type it literally, so anyone who reads this can see if I forgot something.
In a newely created WPF project, I added New Item -> Local Database,
and then Dataset -> Finish and in that database I'v created a table with 2 columns: ID and name.
Then Add -> New Item -> ADO.NET Entity Data Model for that base
I have made a button with a click event which should add a new values in table columns, but
nothing happends in the database. This is the code I have written:
private void button1_Click(object sender, RoutedEventArgs e)
{
Database1Entities DbTest = new Database1Entities();
Table1 table = new Table1
{
Name = "John"
};
DbTest.AddToTable1(table);
DbTest.SaveChanges();
}
When I execute program, in debug I have the following error:
An error occurred while updating the entries. See the inner exception for details.
I don't understand what's wrong, because when I do the same thing with Database created in SQL server, and connecting to VS2010 via EDM, everything works perfectly.

Unable to update database using savechanges() in Entity Framework

I am trying the Model first approach of Entity Framework. I am a newbie to Entity Framework and learning from here and coded the same way. But I am getting this error
Unable to update the EntitySet 'Users' because it has a DefiningQuery and no <InsertFunction> element exists in the <ModificationFunctionMapping> element to support the current operation.
the code I am running is:
protected void Page_Load(object sender, EventArgs e)
{
User use = new User();
use.First_Name = "Arslan";
use.Last_Name = "Akbar";
use.Password = "alone";
use.Email = "arslan#gmail.com";
use.Designation = "Head";
using (CustomersEntities ce = new CustomersEntities())
{
//int count = ce.Users.Count();
//count++;
// use.Id = count;
ce.Users.Add(use);
ce.SaveChanges();
// ce.Users.Create(use);
// ce.SaveChanges();
//ce.Entry(use).State = System.Data.EntityState.Added;
}
}
I am unable to identify the issue.
There are a number of things that could be causing this, some are covered in comments above:
Trying to update a view
Trying to update a table that does not have a primary key
The primary key was added to the table directly, not via model first, the C# code therefore does not see the primary key
There is a reference to another table and there are some problems with the keys
I would take a backup, delete what you have and then try again from scratch.
PS: I just worked through the example in your link, it worked fine for me.
What I noticed was that the Add method was "AddObject" not "Add". You should check the target framework for your project.
Database table doesn't have a primary key, in your data base set primary key for user table.

Entity Framework, SQLite and Lazy loading

Hi I had developed a C# Budget application using SQL Compact and EF4, I created the EF model through the VS2010 Entity Data Model template. It is all working very well. However I am considering developing a iPhone app to support cash transactions and thought it would be better to have the back end DB supported on both platforms. After creating the SQLite DB and creating a new model I have come across a problem when trying to access referenced data via the Navigation properties in my model. I am getting a NullReferenceException when trying to display a property of a referenced table.
When using the following code I get the exception on the last line:
BudgetEntities budget = new BudgetEntities();
var accounts = budget.BankAccounts.ToList();
foreach (BankAccount a in accounts)
{
Console.WriteLine("Name:" + a.Description);
Console.WriteLine("Number:" + a.AccountNumber);
Console.WriteLine("Type:" + a.BankAccountType.AccountType); //Exception occurs here.
}
Strange thing is that the exception doesn't occur in this example. I'm not sure what is going on?
BudgetEntities budget = new BudgetEntities();
var accoutTypes = budget.BankAccountTypes;
var account = new BankAccount();
account.ID = Guid.NewGuid();
account.AccountTypeID = accoutTypes.First(t => t.AccountType.StartsWith("Credit")).ID;
account.BSB = "3434";
account.AccountNumber = "32323";
account.Description = "Test";
account.TrackingAccount = true;
budget.AddObject("BankAccounts", account);
budget.SaveChanges();
var accounts = budget.BankAccounts.ToList();
foreach (BankAccount a in accounts)
{
Console.WriteLine("Name:" + a.Description);
Console.WriteLine("Number:" + a.AccountNumber);
Console.WriteLine("Type:" + a.BankAccountType.AccountType); //Exception doesn't happen.
}
This is only a simple example and I know I could fix it by adding .Include("BankAccountTypes") to the query however I have other queries that are quite complex that are creating object which include properties from referenced object with in the query and I am not quite sure how to get around this issue for them.
EDIT:
After having a break between projects I have come back to this problem and I have finally resolved my problem. it had nothing to do with the code. It was with the data. I had converted a SQL Compact database to SQLite via a dump and load and had the syntax wrong for my Guid column data. I was inserting the Guid as '7cee3e1c-7a2b-462d-8c3d-82dd6ae62fb4' when it should have been x'7cee3e1c7a2b462d8c3d82dd6ae62fb4'
Hopefully the hair I pulled out working through this problem will grow back :)
Thanks everyone for your input.
In second example your code snippet begins with:
var accoutTypes = budget.BankAccountTypes;
This loads all bank account types to your application and you don't need lazy loading anymore (EF will automatically recognize that these entities were already loaded and fix relations with bank accounts).
First check if your account class is dynamic proxy (just check type of a in the debugger). If it is not you made some mistake in the class definition and lazy loading will not work. Next check if lazy loading is enabled on your context instance (budget.ContextOptions.LazyLoadingEnabled property).
Make sure the BankAccountType property is declared virtual in BudgetEntities.

An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext. This is not supported

My project is divided to PresentationLayer, BusinesLogicLayer and DataAccessLayer. Every created object goes through these layers.
In simplifying:
SetFilter.xaml.cs
FilterFactory fFactory = new FilterFactory();
Filter myFilter = fFactory.Create(someClient, time, message);
FilterBLO filterBLO = new FilterBLO();
filterBLO.Save(myFilter);
FilterBLO.cs
FilterDAO filterDAO = new FilterDAO();
using (TransactionScope transcope = new TransactionScope())
{
filterDAO.Save(myFilter);
transcope.Complete()
}
FilterDAO.cs
using(DBDataContext dbdc = new DBDataContext)
{
dbdc.Filter.InsertOnSubmit(myFilter);
changeSet = dbdc.GetChangeSet();
dbdc.SubmitChanges()
}
Filter is connected with table Client using ClientFilter table containing FilterID and ClientID. (many-to-many relationship)
If I create new 3 objects everything's ok, but if I'm getting existing Client in database (also using ClientBLO and ClientDAO so in separate TransactionScope and separate DBDataContext) I get error:
An attempt has been made to Attach or Add an entity that is not new,
perhaps having been loaded from another DataContext. This is not
supported.
(I searched other similar threads but I didn't found solution to my problem.)
And finally my question
How should I save myFilter if Client exists in database. I tried Attach() it to datacontext in FilterDAO.cs but I get the same error.
You have to obtain Client from the database with the same DataContext you use to InsertOnSubmit the Filter; then you have to set Client value in the Filter object with that object before InsertOnSubmit.

Categories