Skip to content

Instantly share code, notes, and snippets.

@tombowers
Last active March 8, 2023 04:32
Show Gist options
  • Star 28 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save tombowers/6f99eb132cfec185b951 to your computer and use it in GitHub Desktop.
Save tombowers/6f99eb132cfec185b951 to your computer and use it in GitHub Desktop.
Entity Framework - Update without Select
var id = 1;
using (var db = new entityContext())
{
// Select entity
var entity = db.dbset.FirstOrDefault(e => e.ID == id);
if (entity != null)
{
// Remove Entity
db.dbset.Remove(entity);
db.SaveChanges();
}
}
var id = 1;
using (var db = new entityContext())
{
// Create stub entity
var entity = new myEntity { ID = id };
// Attach the entity to the context.
db.dbset.Attach(entity);
// Remove the entity. This marks it for deletion
db.dbset.Remove(entity);
// Save changes. EF will see that the entity state has changed,
// and process it accordingly. In this case performing a delete query.
db.SaveChanges();
}
try
{
using (var db = new dbContext())
{
// Create new stub with correct id and attach to context.
var entity = new myEntity { PageID = pageid };
db.Pages.Attach(entity);
// Now the entity is being tracked by EF, update required properties.
entity.Title = "new title";
entity.Url = "new-url";
// EF knows only to update the propeties specified above.
db.SaveChanges();
}
}
catch (DataException)
{
// process exception
}
@farhadnowzari
Copy link

How would you Upsert without select? the upsert would be a collection of entities received by a method which contains DTOs that may not be available in the database so you can NOT use attach range for example.
One way theoretically is to load the ExistingData partially with a select like dbContext.People.Where(x => x exists in requested collection).Select(x => new Person { Id = x.Id, State = x.State }).ToList() which just loads a part of the entity and not the heavy parts. But here if you update one of these returned entityItems from this collection it will not update because of the new Person its not tracking it and you also cannot say dbContext.Entry<Person>(person).State = Modified because it will throw an error and will tell you that ef core is already "Tracking" it.
So what to do.
One way would be to detach all of them from the ChangeTracker and then do the state change and it will do the update but not just on one field even if you say dbContext.Entry<Person>(person).Property(x => x.State).Modified = true. It will overwrite every fields that you haven't read from the database to their default value and it will make a mess in the database.
The other way would be to read the ChangeTracker entries and update them but it will also overwrite and it will consider like everything is chanaged.
So techinically I don't know how ef core can create the following SQL,

update People set state = 'Approved' where state != 'Approved'

without updating anything else. or loading the person first completely.

The reason for not loading your data is that you may want to update like 14000 records and those records are really heavy to load because they contain byte[] and have images stored on them for example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment