Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieving entity from context after Add() yet before SaveChanges() has been called

Let's assume I have a file with multiple rows each representing a Person, the Person entity has an identity column that is also the primary key. Assuming that a Person can be repeated in the file, if it is, perhaps I want to do a last entry wins scenario. In the example below I use a repository to retrieve a person from the database by the social security number. The issue is that when the same SSN shows up again in the file, the repository still returns a null, even though technically that person with that SSN has already been added to the context (SaveChanges hasn't been called yet). I realize I can work around this by tracking myself which Person objects have already been added. I am wondering what is the best practice for this scenario. Thanks.

foreach(row in fileRows)
{
    Person person = personRepository.GetBySSN(row.SSN);

    if(person == null)
    {
        //insert logic
    }
    else
    {
        //update logic
    }
}

personRepository.SaveChanges();
like image 968
e36M3 Avatar asked Jun 23 '11 16:06

e36M3


People also ask

What does the DbContext SaveChanges () method return?

Returns. The number of state entries written to the underlying database. This can include state entries for entities and/or relationships.

How do I get ID before SaveChanges?

You can retreive an ID before calling . SaveChanges() by using the Hi/Lo alhorithm. The id will be assigned to the object once it is added to dbcontext.

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.

When should you call context SaveChanges?

If you need to enter all rows in one transaction, call it after all of AddToClassName class. If rows can be entered independently, save changes after every row.


1 Answers

I think I can give the same answer I gave here

To persist an entity you usually add it to it's DbSet in the context.

For example

var bar = new Bar();
bar.Name = "foo";
var context = new Context();
context.Bars.Add(bar);

Surprisingly, querying context.Bars, the just added entity cannot be found

var howMany = context.Bars.Count(b => b.Name == "foo");
// howMany == 0

After context.SaveChanges() the same line will result 1

The DbSet seems unaware to changes until they're persisted on db.

Fortunately, each DbSet has a Local property that acts like the DbSet itself, but it reflect all in-memory operations

var howMany = context.Bars.Local.Count(b => b.Name == "foo");
// howMany == 1

You can also use Local to add entities

context.Bars.Local.Add(bar);

and get rid of the weird behavior of Entity Framework.

like image 185
Arialdo Martini Avatar answered Sep 22 '22 21:09

Arialdo Martini