Unable to update database using savechanges() in Entity Framework - c#

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.

Related

c# using a binding source to add row to an sql table with incremental identity field

I have a program I created in Visual studio. The program is basically a place for everyone to store passwords for company and external accounts. I want to further this application by automatically creating the company accounts when I create a new user. I approached this by using the binding source. I can get the row into the database but it doesn't use the sql supplied auto increment. I will post the code but I am trying to figure out if I went about this the wrong way. I am not 100% familiar with how the connector and classes that visual studio create when you connect the solution to the database. I am not looking for code to help me do this I am looking for explanations and guidance. If responding with code please help me understand by explaining the code.
DataSet.AccountsRow newdomainuserrow = DBDataSet.Accounts.NewAccountsRow();
newdomainuserrow.USer = userIDTextBox.Text.ToString();
newdomainuserrow.UserName = userIDTextBox.Text.ToString();
System.DateTime moment = new DateTime();
newdomainuserrow.Password = moment.Year;
newdomainuserrow.AccountName = "Domain";
drawingNumDBDataSet.Accounts.Rows.Add(newdomainuserrow);
MessageBox.Show("User Saved");
this.Validate();
this.usersBindingSource.EndEdit();
this.accountBindingSource.Endedit();
this.tableAdapterManager.UpdateAll(this.DataSet);
All help is greatly appreciated.
Matt
I found a solution. The id field is not longer an identity autoincrement field. To increment the id field one by one programmatically like I need to I wrote a simply while statement to get all numbers that were not used. This works if there is a deleted row it will insert one where there is one missing. here is the code I used.
Boolean gotnum;
gotnum = false;
int idnum = 1;
while (gotnum != true)
{
DrawingNumDBDataSet.AccountsRow actrw = drawingNumDBDataSet.Accounts.FindById(idnum);
idnum++;
if (actrw==null)
{
gotnum = true;
idnum--;
}
}
I then set the Id field = to idnum. This is probably not the best practice but it is the best I could come up with.

dynamically create link tables and rename them in access 2007/2003 with c#

I'm looking to be able to dynamically create linked tables with C# in an accdb/mdb existing file. Is this possible? The idea would be for every linked table ALREADY in a given access database dynamically create a new linked table and then the second part of the problem would be to then rename name this newly created table to the pre existing table.
If its not already clear there is a migration going on from one database to another so every pre existing table has an equivalent table in the new database but they need to have the same name in the Access database in order for the queries to work etc.
Is this even possible?
EDIT:
I have created a test database that contains one linked table to an ODBC database. I have also created a simple query that just counts the rows. My C# code runs the query first and then attempts to change the connection string with the code:
var dbe = new DBEngine();
Database db = dbe.OpenDatabase(#"C:\Users\x339\Documents\Test.accdb");
foreach (TableDef tbd in db.TableDefs)
{
if (tbd.Connect.Length > 5)
{
if (tbd.Connect.Substring(0, 5).Equals("ODBC;"))
{
tbd.Connect = tbd.Connect.Replace("ODBC;DSN=ILACFEUC;UID=cloaseuc;DBQ=ILACFEUC;DBQ=W;APA=T;EXC=F;FEN=T;QTO=F;FRC=10;FDL=10;LOB=T;RST=T;BTD=F;BNF=F;BAM=IfAllSuccessful;NUM=NLS;DPM=F;MTS=F;MDI=F;CSR=F;FWC=F;FBS=64000;TLO=0;MLD=0;ODA=F;;TABLE=CLOASEUCDBA.T_BASIC_POLICY", "ODBC;DSN=ILACFEUC;UID=cloaseuc;DBQ=ILACFEUC;DBQ=W;APA=T;EXC=F;FEN=T;QTO=F;FRC=10;FDL=10;LOB=T;RST=T;BTD=F;BNF=F;BAM=IfAllSuccessful;NUM=NLS;DPM=F;MTS=F;MDI=F;CSR=F;FWC=F;FBS=64000;TLO=0;MLD=0;ODA=F;;TABLE=CLOASEUCDBA.T_BILLING_INFORMATION");
tbd.RefreshLink();
}
}
}
however it is not working. If I open the database up in access the connection string is unchanged?
It sounds like you really just want to change the external database to which the existing linked tables are connected. In that case you could do it in C# like this:
// This code requires the following COM reference in your project:
//
// Microsoft Office 14.0 Access Database Engine Object Library
//
// and the declaration
//
// using Microsoft.Office.Interop.Access.Dao;
//
// at the top of the class file
var dbe = new DBEngine();
Database db = dbe.OpenDatabase(#"C:\Users\Public\FrontEnd.accdb");
foreach (TableDef tbd in db.TableDefs)
{
if (tbd.Connect.Length > 10)
{
if (tbd.Connect.Substring(0, 10).Equals(";DATABASE="))
{
tbd.Connect = tbd.Connect.Replace("oldBackEnd.accdb", "newBackEnd.accdb");
tbd.RefreshLink();
}
}
}
db.Close();

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.

Entity Framework insert doesn't work

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.

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.

Categories