I’m following this tutorial Creating Master-Details Windows Forms with the Entity Framework
but the db.Savechanges()
isn’t working if I modified some column or add a new row. According to this video tutorial it will work but it doesn’t.
Product_Form.cs
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;
namespace RemoteSynchronizer
{
public partial class Product : Form
{
ProductsEntities db = new ProductsEntities();
public Product()
{
InitializeComponent();
}
private void Product_Form_Load(object sender, EventArgs e)
{
product_DBindingSource.DataSource = db.Product_D.ToList();
}
private void bindingNavigatorAddNewItem_Click(object sender, EventArgs e)
{
}
private void product_DBindingNavigatorSaveItem_Click(object sender, EventArgs e)
{
// Product_D obj = new Product_D();
// obj.PCode = pCodeTextBox.Text;
// obj.Name = nameTextBox.Text;
// obj.Batch = batchTextBox.Text;
// obj.Expiry = expiryTextBox.Text;
// obj.Price = priceTextBox.Text;
//try
// {
// Product_D temp = db.Product_D.Single(t => t.PCode == pCodeTextBox.Text);
// MessageBox.Show("Product Exists");
// }
// catch
// {
// db.Product_D.Add(obj);
db.SaveChanges();
//}
}
private void bindingNavigatorDeleteItem_Click(object sender, EventArgs e)
{
}
}
}
When I try to use comment method in code it gives an error
Error
************** Exception Text **************
System.Data.Entity.Infrastructure.DbUpdateException: Unable to update the EntitySet 'Product_D' because it has a DefiningQuery and no <InsertFunction> element exists in the <ModificationFunctionMapping> element to support the current operation. ---> System.Data.UpdateException: Unable to update the EntitySet 'Product_D' because it has a DefiningQuery and no <InsertFunction> element exists in the <ModificationFunctionMapping> element to support the current operation.
at System.Data.SqlClient.SqlGen.DmlSqlGenerator.ExpressionTranslator.Visit(DbScanExpression expression)
at System.Data.Common.CommandTrees.DbScanExpression.Accept(DbExpressionVisitor visitor)
at System.Data.SqlClient.SqlGen.DmlSqlGenerator.GenerateInsertSql(DbInsertCommandTree tree, SqlVersion sqlVersion, List`1& parameters)
at System.Data.SqlClient.SqlGen.SqlGenerator.GenerateSql(DbCommandTree tree, SqlVersion sqlVersion, List`1& parameters, CommandType& commandType, HashSet`1& paramsToForceNonUnicode)
at System.Data.SqlClient.SqlProviderServices.CreateCommand(DbProviderManifest providerManifest, DbCommandTree commandTree)
at System.Data.SqlClient.SqlProviderServices.CreateCommand(DbCommandTree commandTree)
at System.Data.Mapping.Update.Internal.UpdateTranslator.CreateCommand(DbModificationCommandTree commandTree)
at System.Data.Mapping.Update.Internal.DynamicUpdateCommand.CreateCommand(UpdateTranslator translator, Dictionary`2 identifierValues)
at System.Data.Mapping.Update.Internal.DynamicUpdateCommand.Execute(UpdateTranslator translator, EntityConnection connection, Dictionary`2 identifierValues, List`1 generatedValues)
at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter)
at System.Data.EntityClient.EntityAdapter.Update(IEntityStateManager entityCache)
at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options)
at System.Data.Entity.Internal.InternalContext.SaveChanges()
--- End of inner exception stack trace ---
at System.Data.Entity.Internal.InternalContext.SaveChanges()
at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
at System.Data.Entity.DbContext.SaveChanges()
at RemoteSynchronizer.Product.product_DBindingNavigatorSaveItem_Click(Object sender, EventArgs e) in e:\Study\Project\RemoteSynchronizer\RemoteSynchronizer\Product_Form.cs:line 50
at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
at System.Windows.Forms.ToolStripButton.OnClick(EventArgs e)
at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
at System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
at System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met)
at System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met)
at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ToolStrip.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
************** Loaded Assemblies **************
mscorlib
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.18010 built by: FX45RTMGDR
CodeBase: file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/mscorlib.dll
----------------------------------------
RemoteSynchronizer
Assembly Version: 1.0.0.0
Win32 Version: 1.0.0.0
CodeBase: file:///E:/Study/Project/RemoteSynchronizer/RemoteSynchronizer/bin/Debug/RemoteSynchronizer.exe
----------------------------------------
System.Windows.Forms
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System.Drawing
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
System
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.18016 built by: FX45RTMGDR
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
System.Configuration
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Configuration/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll
----------------------------------------
System.Xml
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Xml/v4.0_4.0.0.0__b77a5c561934e089/System.Xml.dll
----------------------------------------
System.Web
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_32/System.Web/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Web.dll
----------------------------------------
System.Core
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Core/v4.0_4.0.0.0__b77a5c561934e089/System.Core.dll
----------------------------------------
EntityFramework
Assembly Version: 5.0.0.0
Win32 Version: 5.0.20627.0
CodeBase: file:///E:/Study/Project/RemoteSynchronizer/RemoteSynchronizer/bin/Debug/EntityFramework.DLL
----------------------------------------
System.Data.Entity
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Data.Entity/v4.0_4.0.0.0__b77a5c561934e089/System.Data.Entity.dll
----------------------------------------
Anonymously Hosted DynamicMethods Assembly
Assembly Version: 0.0.0.0
Win32 Version: 4.0.30319.18010 built by: FX45RTMGDR
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_32/mscorlib/v4.0_4.0.0.0__b77a5c561934e089/mscorlib.dll
----------------------------------------
Accessibility
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/Accessibility/v4.0_4.0.0.0__b03f5f7f11d50a3a/Accessibility.dll
----------------------------------------
System.Data
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_32/System.Data/v4.0_4.0.0.0__b77a5c561934e089/System.Data.dll
----------------------------------------
System.Transactions
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_32/System.Transactions/v4.0_4.0.0.0__b77a5c561934e089/System.Transactions.dll
----------------------------------------
System.Numerics
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Numerics/v4.0_4.0.0.0__b77a5c561934e089/System.Numerics.dll
----------------------------------------
System.Data.OracleClient
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_32/System.Data.OracleClient/v4.0_4.0.0.0__b77a5c561934e089/System.Data.OracleClient.dll
----------------------------------------
System.Xml.Linq
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Xml.Linq/v4.0_4.0.0.0__b77a5c561934e089/System.Xml.Linq.dll
----------------------------------------
System.EnterpriseServices
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_32/System.EnterpriseServices/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.EnterpriseServices.dll
----------------------------------------
EntityFrameworkDynamicProxies-RemoteSynchronizer
Assembly Version: 1.0.0.0
Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Data.Entity/v4.0_4.0.0.0__b77a5c561934e089/System.Data.Entity.dll
----------------------------------------
System.Runtime.Serialization
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Runtime.Serialization/v4.0_4.0.0.0__b77a5c561934e089/System.Runtime.Serialization.dll
----------------------------------------
System.ComponentModel.DataAnnotations
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.17929
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.ComponentModel.DataAnnotations/v4.0_4.0.0.0__31bf3856ad364e35/System.ComponentModel.DataAnnotations.dll
----------------------------------------
Microsoft.SqlServer.Types
Assembly Version: 11.0.0.0
Win32 Version: 2011.0110.2100.060 ((SQL11_RTM).120210-1917 )
CodeBase: file:///C:/Windows/assembly/GAC_MSIL/Microsoft.SqlServer.Types/11.0.0.0__89845dcd8080cc91/Microsoft.SqlServer.Types.dll
----------------------------------------
************** JIT Debugging **************
To enable just-in-time (JIT) debugging, the .config file for this
application or computer (machine.config) must have the
jitDebugging value set in the system.windows.forms section.
The application must also be compiled with debugging
enabled.
For example:
<configuration>
<system.windows.forms jitDebugging="true" />
</configuration>
When JIT debugging is enabled, any unhandled exception
will be sent to the JIT debugger registered on the computer
rather than be handled by this dialog box.
How to get rid of this problem? I’m trying to solve this by simple method db.savechanges()
but it won’t work.
Before going through my answer, you must check, if you are attaching the item as shown in excepted answer or check this code:.
if (dbStudentDetails != null && dbStudentDetails.Id != 0)
{
// update scenario
item.Id = dbStudentDetails.Id;
_context.Entry(dbStudentDetails).CurrentValues.SetValues(item);
_context.Entry(dbStudentDetails).State = EntityState.Modified;
}
else
{
// create scenario
_context.StudentDetails.Add(item);
}
await _context.SaveChangesAsync();
If above solution doesn’t work, then check the below answer.
Saw a very wired issue, and thought to must answer this. as this can
be a major issue if you have lots of constraints and indexes in your
SQL.
db.SaveChanges() wasn’t throwing any error, but not working (I have tried Exception or SqlException). This was not working because the Unique constraint was not defined properly while creating the Entity Models.
How you can Identified the issue:
- I connected my SQL Server and opened the SQL Profiler.
- Just before the db.SaveChanges(), I cleared all my profiler logs and ran the db.SaveChanges(). It logged the statement. I copied the script from the profiler and ran the script in SQL Server.
- And bingo, I can see the actual error, which is being thrown at SQL Server side.
(images: have some hints, how you can get the execute statement from Profiler and run on sql server)
What you can do For Entity Framework Core:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Students>().HasIndex(p => new { p.RollNumber, p.PhoneNumber }).IsUnique(true).IsClustered(false).HasDatabaseName("IX_Students_Numbers");
}
What you can do For Entity Framework 6 and below:
using System.Data.Entity.ModelConfiguration;
internal partial class StudentsConfiguration : EntityTypeConfiguration<Students>
{
public StudentsConfiguration()
{
HasIndex(p => new { p.RollNumber, p.PhoneNumber }).IsUnique(true).IsClustered(false).HasName("IX_Students_Numbers");
}
}
अजपा जप आणि शांभवी मुद्रा ऑनलाईन कोर्स : श्वास, मंत्र, मुद्रा आणि ध्यान यांच्या सहाय्याने मनःशांती, एकाग्रता, चक्र संतुलन आणि कुंडलिनी जागृती. अधिक माहिती आणि आगामी तारखांसाठी येथे जा.
Passing data from one controller
Beginners often ask this question — «What course of action should I take when a
call to SaveChanges() fails?» The answer may vary based on a given situation and
requirement. However, in many cases the following course of actions can be
performed:
- Trap the exception caused by the failed call to SaveChanges().
- Find out all the errors that occurred during the SaveChanges() call.
- Find out which entities caused the errors.
- Either display the errors and entities causing errors to the user or log
that information somewhere. - Based on whether an entity was added, modified or deleted rollback its
effect.
Let’s see how the above steps can be performed by developing a simple console
application.
Begin by creating a new project of type Console Application. Then add Models
folder to it and generate ADO.NET Entity Data Model for the Customers and
Employees tables of the Northwind database. The following figure shows the
Customer and Employee entities:
Now add the following code in the Main() method:
static void Main(string[] args) { NorthwindEntities db = new NorthwindEntities(); Customer obj1 = new Customer(); obj1.CustomerID = "This is a long CustomerID"; obj1.CompanyName = "Abcd"; obj1.ContactName = "Abcd"; obj1.Country = "USA"; db.Customers.Add(obj1); Employee obj2 = db.Employees.Find(1); obj2.FirstName = "This is a long first name value"; db.SaveChanges(); }
The above code attempts to add a new Customer to the Customers table and also
attempts to modify an existing Employee with EmployeeID of 1. Notice that the
code deliberately sets CustomerID property of the Customer object and FirstName
property of the Employee object to some long value — something that won’t fit in
the column length.
When you can SaveChanges() obviously it is going to throw an exception. The
following figure shows the exception thrown by an unsuccessful call to
SaveChanges().
As shown above an unsuccessful call to SaveChanges() threw
DbEntityValidationException exception. This exception class can be used to
obtain more information about all the errors that occurred during the
SaveChanges() call.
Now modify the Main() as shown below:
try { db.SaveChanges(); } catch (DbEntityValidationException ex) { foreach (DbEntityValidationResult item in ex.EntityValidationErrors) { // Get entry DbEntityEntry entry = item.Entry; string entityTypeName = entry.Entity.GetType().Name; // Display or log error messages foreach (DbValidationError subItem in item.ValidationErrors) { string message = string.Format("Error '{0}' occurred in {1} at {2}", subItem.ErrorMessage, entityTypeName, subItem.PropertyName); Console.WriteLine(message); } } }
Now the call to SaveChanges() is wrapped inside a try…catch block. The
catch block traps DbEntityValidationException exception. The
EntityValidationErrors collection of DbEntityValidationException class contains
a list of validation errors. Each item of EntityValidationErrors collection is
of type DbEntityValidationResult. Instead of showing a generic message the above
code forms a descriptive error messages. This is done by finding which all
entities caused errors. In each iteration of the outer foreach loop, the entry
causing the error is accessed using the Entry property of
DbEntityValidationResult class. The Entry property is of type DbEntityEntry. The
Entity property of this DbEntityEntry gives you the entity that caused the
error. The above code simply obtains a fully qualified name of the entity type
(for example, ProjectName.Models.Customer and ProjectName.Models.Employee).
The inner foreach loop iterates through the ValidationErrors collection of
DbEntityValidationResult under consideration. Each item of ValidationErrors
collection is of type DbValidationError. The PropertyName and ErrorMessage
properties of DbValidationError class give you the entity property that caused
the error (such as CustomerID and FirstName) and the actual error message. These
properties along with the entity type name are used to form a descriptive error
message. In this example the error message is displayed on the console but you
can log it in some text file if you so wish. The following figure shows how the
error messages are displayed on the console.
So far we displayed the descriptive error messages to the end user. Now it’s
time to rollback the changes so that the entities causing error are either
isolated from the model or the changes are discarded (in case of modified
entities). Modify the code in the catch block as shown below:
... ... foreach (DbValidationError subItem in item.ValidationErrors) { string message = string.Format("Error '{0}' occurred in {1} at {2}", subItem.ErrorMessage, entityTypeName, subItem.PropertyName); Console.WriteLine(message + "\n\n"); } // Rollback changes switch (entry.State) { case EntityState.Added: entry.State = EntityState.Detached; break; case EntityState.Modified: entry.CurrentValues.SetValues(entry.OriginalValues); entry.State = EntityState.Unchanged; break; case EntityState.Deleted: entry.State = EntityState.Unchanged; break; }
The above code checks the State property of the DbEntityEntry causing the
error. The State property is of enumeration type — EntityState. If the current
State is Added, it is changed to Detached so that the entry won’t be considered
a part of the DbSet for future calls. If the current State is Modified, the
modified values (the values causing the error) are flushed out by replacing them
with the OriginalValues. Notice how the original values are obtained using
SetValues() method and OriginalValues property. If the State is Deleted, it is
changed to Unchanged so that the entity is undeleted.
Once you display the errors and rollback any changes to the entities causing
the errors, you may give another chance to the user to make the changes and then
call SaveChanges() again.
That’s it for now! Keep coding !!
I was debugging an issue with DbContext.SaveChanges
which was neither saving changes to the database nor throwing any exceptions, and after solving the issue I found it interesting to list some of the reasons that might cause this issue and how to detect them.
The possible reasons fall into four main categories.
- Wrong destination
- SaveChanges isn’t called properly
- Changes are not tracked
- Database does not preserve changes
Wrong destination
You might be expecting your changes to be saved somewhere but your DbContext
is saving it somewhere else. For example the connection string is not the one you expect. It’s a common mistake that some developers change the connection string in the configuration file of the data access project instead of the startup project.
To check which connection string your DbContext is using you can do this.
// check the value of the connection string
string connection = dbContext.Database.GetConnectionString();
dbContext.SaveChanges();
Enter fullscreen mode
Exit fullscreen mode
Another reason could be that you are checking the wrong database table, maybe your EF entity is mapped to another table (e.g. via some fluent API configuration), you can check that as follows.
var mapping = dbContext.Model.FindEntityType(typeof(YourEntity));
string schema = mapping.GetSchema();
string table = mapping.GetTableName();
dbContext.SaveChanges();
Enter fullscreen mode
Exit fullscreen mode
Make sure that schema
and table
are as you expect.
SaveChanges isn’t called properly
You might be calling SaveChanges
on a different instance of your DbContext
, and that might not be easy to spot in some complex codebases where changes to the DbContext
are far from the call to SaveChanges
.
EF assigns a unique ID for each DbContext
instance which could be used to check that.
dbContext.Employees.Add(newEmp);
string id1 = dbContext.ContextId;
.....
// elsewhere in the codebase
string id2 = dbContext.ContextId;
dbContext.SaveChanges();
Enter fullscreen mode
Exit fullscreen mode
You have to confirm that id1
equals id2
.
Another silly mistake might be calling SaveChangeAsync
without awaiting it (i.e. using await keyword) which absorbs exceptions and obviously to fix that you just need to await the call await dbContext.SaveChangesAsync();
.
Changes are not tracked
The EF Change Tracker is the component responsible for detecting the changes that should be updated in the database. There are many reasons why change tracker doesn’t see/consider your changes. To check if this is the case you might do something like this.
bool hasChanges = dbContext.ChangeTracker.HasChanges(); // should be true
int updates = dbContext.SaveChanges(); // should be > 0
Enter fullscreen mode
Exit fullscreen mode
When hasChanges
is false or updates
is 0 then the Change Tracker couldn’t detect your changes, maybe because you’re changing the value of a NotMapped
property like FullName
in the entity below.
public class Person
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
[NotMapped]
public string FullName { get; set; }
}
Enter fullscreen mode
Exit fullscreen mode
Or maybe you are changing a disconnected/detached entity which is a common scenario in web applications when you receive an object from the client-side, one way to fix this is by changing the entry state.
db.Entry(myEntity).State = EntityState.Modified; // use an appropriate state
dbContext.SaveChanges();
Enter fullscreen mode
Exit fullscreen mode
Database not preserving changes
One of the sneakiest issues is when you begin a database transaction but you don’t commit it, it’s sneaky because in this case you will see that the Change Tracker detected your changes (i.e. hasChanges
equals true, updates
will be greater than 0) and the SQL Server Profiler will show that the insert statement executed successfully on your database but still you won’t find any changes, check this.
using (var context = new MyContext())
{
var transaction = context.Database.BeginTransaction(IsolationLevel.Serializable);
context.Employees.Add(newEmployee);
int updates = context.SaveChanges(); // updates == 1 even when the transaction is not committed
}
Enter fullscreen mode
Exit fullscreen mode
In my case that was the reason why SaveChange
wasn’t working and the BeginTransaction
call was not as clear as in the above snippet, it was buried into a forsaken area in the codebase, where someone was trying something and forgot to remove it.
To detect whether your DbContext
has a current transaction you can check if context.Database.CurrentTransaction
is not null.
// use this to check if a database transaction has begun
var hasTransaction = context.Database.CurrentTransaction != null;
context.SaveChanges();
Enter fullscreen mode
Exit fullscreen mode
When hasTransaction
is true you should commit your transaction by calling transaction.Commit
after calling SaveChanges
, otherwise your changes will not be saved.
using (var context = new MyContext())
{
var transaction = context.Database.BeginTransaction(IsolationLevel.Serializable);
context.Employees.Add(newEmployee);
int updates = context.SaveChanges();
transaction.Commit(); // solves the problem
}
Enter fullscreen mode
Exit fullscreen mode
Another issue could be that there’s something that reverts your changes like a database trigger. You can test that by disabling all triggers on your table
Disable Trigger All on YourTableName
Enter fullscreen mode
Exit fullscreen mode
Or even on the whole database
Disable Trigger All on Database.
Enter fullscreen mode
Exit fullscreen mode
You can also check this in the SQL Server Profiler but you have to make sure that the SP:StmtStarting
and SP:StmtCompleted
events are selected in the «Trace Properties» dialog.
Expand the «Stored Procedures» node (Yes, there’s no triggers node), then check SP:StmtStarting
and SP:StmtCompleted
events.
If there are any triggers that update your table, then you will see their update statements in the SQL profiler.
Another prevalent issue (on Stackoverflow) in this category is when you are using LocalDb where the .mdf file could be overwritten every time you build your project, to fix that you need to change the CopyToOutput action to overwrite the file only if newer.
The database might not preserve your changes if your changes affect a precision level that is not supported by the data type of the database field.
A common example for this is the datetime
field in MS SQL Server which has less precision than the DateTime
object in .NET, check the code below.
myEntity.Time = DateTime.Parse("2020–01–01 13:45:59.2501234"); // the last 4 digits will never be saved
dbContext.SaveChanges();
Enter fullscreen mode
Exit fullscreen mode
The update statement that EF generates for the above snippet will be like this.
exec sp_executesql N'SET NOCOUNT ON;
UPDATE [MyTable] SET [Time] = @p0
WHERE [Id] = @p1;
SELECT @@ROWCOUNT;
',N'@p1 int,@p0 datetime',@p1=1,@p0='2020–01–01 13:45:59.250'
Enter fullscreen mode
Exit fullscreen mode
As you can see the SQL statement doesn’t include the fraction part of the DateTime
object. Note that this issue is one of the issues that can be spotted via the SQL Server profiler.
Follow us on Social Media
Entity Framework – Error On Db.Savechanges() With Code Examples
In this session, we’ll try our hand at solving the Entity Framework – Error On Db.Savechanges() puzzle by using the computer language. The code that follows serves to illustrate this point.
Check to see if the database column name does not allow null values and you are passing them.
We were able to figure out how to solve the Entity Framework – Error On Db.Savechanges() code by looking at a range of other samples.
How do I override SaveChanges in Entity Framework?
As stated earlier, here we will override the default “SaveChanges()” method of Entity Framework.Now let’s analyze this “SaveChanges()” method.
- var selectedEntityList = ChangeTracker.Entries()
- .Where(x => x.Entity is EntityInformation &&
- (x. State == EntityState. Added || x. State == EntityState. Modified));
What is DB SaveChanges ()?
DbContext.SaveChanges Method (Microsoft.EntityFrameworkCore) Saves all changes made in this context to the database. This method will automatically call DetectChanges() to discover any changes to entity instances before saving to the underlying database.
When would you use SaveChanges false AcceptAllChanges ()?
Sometimes though the SaveChanges(false) + AcceptAllChanges() pairing is useful. The most useful place for this is in situations where you want to do a distributed transaction across two different Contexts. If context1. SaveChanges() succeeds but context2.
How do I update my EF core record?
First, we create a new context and retrieve the existing department data from the database. We modify the Descr field. Since the context is open, it will mark the entity as Modified . Finally, when we call the SaveChanges , the context generates the update SQL statement to persist the change to the database.
How do I update my EF core data?
To update an entity with Entity Framework Core, this is the logical process:
- Create instance for DbContext class.
- Retrieve entity by key.
- Make changes on entity’s properties.
- Save changes.
How do I rollback a transaction in Entity Framework?
A DbContextTransaction object provides Commit() and Rollback() methods to do commit and rollback on the underlying store transaction. This method requires an open underlying stored connection. This method opens a connection if it is not already open. This method will close the connection when Dispose () is called.08-Apr-2021
What is context SaveChanges?
The SaveChanges method of the DbContext prepares the Insert , Update & Delete Queries. It does so by tracking the changes to each of the entities’ Context is tracking. Whenever we query the database for entities, the Context retrieves them and mark the entity as Unchanged .
Does Entity Framework support transactions?
In all versions of Entity Framework, whenever you execute SaveChanges() to insert, update or delete on the database the framework will wrap that operation in a transaction. This transaction lasts only long enough to execute the operation and then completes.01-Apr-2021
Is Savechangesasync a transaction?
According to documentations, the answer to your question is YES, for both EF6 and ‘EF Core`: Ef Core docs: By default, if the database provider supports transactions, all changes in a single call to SaveChanges() are applied in a transaction.11-Mar-2019
How can I update DbContext in Entity Framework core database first?
Entity Framework Core Database First Tutorial
- Create Northwind Database.
- Create New .
- Install Nuget Packages.
- Create Models using Scaffold-DbContext.
- Configure Data Context.
- Registering DBContext with Dependency Injection.
- Scaffold-DbContext options.
- Update existing models.
Follow us on Social Media