Update a Record Without First Querying

Update a record without first querying?

You should use the Attach() method.

Attaching and Detaching Objects

EF Core: updating an entity without querying it first

The documentation for DbContext.Attach Method says:

Begins tracking the given entity and entries reachable from the given entity using the Unchanged state by default, but see below for cases when a different state will be used.

[...]

For entity types with generated keys if an entity has its primary key value set then it will be tracked in the Unchanged state. If the primary key value is not set then it will be tracked in the Added state.

[...]

For entity types without generated keys, the state set is always Unchanged.

[...]

So setting the state to Unchanged is not even necessary.

But be careful. If you set e.g. order.Amount = 0m; to clear the amount, this will not work, as no change will be detected. Write

var order = new OrderEntity()
{
Id = 5,
Amount = 1.00m; // Dummy value unequal 0.00m
};
db.Orders.Attach(order);

// Make the change
order.Amount = 0.00m; // Now, this change will be detected.

db.SaveChanges();

Is it possible to alter a record in rails, without first reading it

Rails models have the update method, which does a SQL select then an SQL update.

Its use is simple (suppose you have a model named Person)

Person.update(person_id, :user_name => 'New Name')

The drawback is that you have to know beforehand the person id.

But then, you will always have to do a query to find out that. You could write your own SQL to change the column value, with a WHERE clause that searches for the param you have.

Rails models have the update_all method, which does only a SQL update without loading the data.
But I wouldn't recommend using it because it doesn't trigger any callbacks or validations that your model may have.

You could use the update_all like this:

Book.update_all "author = 'David'", "title LIKE '%Rails%'"

ps: examples were all taken from the Rails official documentation. If you search for update, or update_all, you'll find both methods in no time.

Take a look there, it's a good place to find out what rails can do.

Rails API link

Update A Record if it exists, else do nothing, including short-cicruit

GOT IT, The following query works to do exactly what I wanted in Mariadb :

UPDATE target_table

LEFT JOIN (complex_queries_and_calculations_to_get_update_value AS update_value) t

ON target_table.ID <> t.update_value -- serves just to have update value in memory,
-- because it needs to be accessed twice to create the updated column value
-- on update, sort of a workaround for CTE + UPDATE in MariaDB

SET target_column = JSON_ARRAY( FORMAT_UPDATE_VALUE(t.update_value),
FORMAT_2_UPDATE_VALUE(t.update_value) )

WHERE ID = 128 AND t.update_value IS NOT NULL;

If the record does not exist, the query takes about 0.0006 secs to execute, without doing anything to the table. If it does exits, it takes 0.0014 secs to execute, while updating the targeted record accordingly. So, it indeed seems to work and resources are saved if the targeted record is not found in target_table. Great thanks to all who helped!

Updating Record Without Query in The Database using Entity frame work

Ok you can ad the record to datacontext like what i did in my code

im going to just update VisitAmp field in my table

NewBranchRequestTbl is my table
nr is new record

var newBran= new NewBranchDataContext();
newBran.NewBranchRequestTbl.AddObject(nr);
newBran.ObjectStateManager.ChangeObjectState(nr, System.Data.EntityState.Unchanged);
newBran.ObjectStateManager.GetObjectStateEntry(nr).SetModifiedProperty("VisitAmp");

So when we call newBran.SaveChanges();

it just updates VisitAmp in NewBranchRequestTbl

WCF methods when using NHibernate: How to update record without first querying

Simply: You don't. The very point of using ORM is to make it so you are working with instances of object, but any changes are automatically persisted to database. Of course there could exist some kind of hack that allows exactly what you want or you can bypass ORM completely and use raw SQL, but then I don't see point of using an ORM framework.

EntityFramework core - Update a collection of data without selecting the entities

Fantastic, I found the solution (You need to also take care about your unit tests).
Entityframework is actually working fine it can be just a lack of experience which I'm documenting here in case anyone else got into the same issue.

Consider that we have an entity for Person which has a profile picture saved as Blob on it which causes that if you do something like the following for let's say 20k people the query goes slow even when you've tried to have enough correct index on your table.
You want to do this query to update these entities based on a request.

var entityIdsToUpdate = request.PeopleDtos.Select(p => p.Id);
var people = dbContext.People.Where(x => entityIdsToUpdate.Contains(x.Id)).ToList();

This is fine and it works perfectly, you will get the People collection and then you can update them based on the given data.
In these kind of updates you normally will not need to update images even if you do, then you need to increase the `TimeOut1 property on your client but for our case we did not need to update the images.
So the above code will change to this.

var entityIdsToUpdate = request.PeopleDtos.Select(p => p.Id);
var people = dbContext.People
.Select(p => new Person {
Id = p.Id,
Firstname = p.Firstname,
Lastname = p.Lastname,
//But no images to load
})
.Where(p => entityIdsToUpdate.Contains(p.Id)).ToList();

But then with this approach, EntityFramework will lose the track of your entities.
So you need to attach it like this and I will tell you how NOT to attach it.

This is the correct way for a collection

dbContext.People.AttachRange(people); //These are the people you've already queried

Now DO NOT do this, you may want to do this because you get an error from the first one from EntityFramework which says the entity is already being tracked, trust it because it already is. I will explain after the code.

//Do not do this
foreach(var entry in dbContext.ChangeTracker.Entries())
{
entry.State = EntityState.Detached;
}
//and then on updating a record you may write the following to attach it back
dbContext.Entry(Person).State = EntityState.Modified;

The above code will cause EntityFramework not to follow the changes on the entities anymore and by the last line you will tell it literally everything edited or not edited is changed and will cause you to LOSE your unedited properties like the "image".

Note: Now what can u do by mistake that even messes up the correct approach.
Well since you are not loading your whole entity, you may assume that it is still fine to assign values to the unloaded ones even if the value is not different than the one in the database. This causes entity framework to assume that something is changed and if you are setting a ModifiedOn on your records it will change it for no good reason.

And now about testing:
While you test, you may get something out from database and create a dto from that and pass the dto with the same dbContext to your SystemUnderTest the attach method will throw an error here which says this entity is already bein tracked because of that call in your test method. The best way would be create a new dbContext for each process and dispose them after you are done with them.

BTW in testing it may happen that with the same dbContext you update an entity and after the test you want to fetch if from the database. Please take note that this one which is returning to you is the "Cached" one by EntityFramework and if you have fetched it in the first place not completely like just with Select(x => ) then you will get some fields as null or default value.
In this case you should do DbContext.Entry(YOUR_ENTRY).Reload().

It is a really complete answer it may not directly be related to the question but all of the things mentioned above if you don't notice them may cause a disaster.

Can I update an EF Entity without querying for it first?

Yes you can. The procedure is to make an entity which resembles the original state of the entity, attach it to the ObjectContext, modify the entity, then SaveChanges. Remember, it is important to attach the entity to the ObjectContext before you modify the entity. There is an example in this post.



Related Topics



Leave a reply



Submit