4

Say Table1 is a table with two columns. Table1ID and Name.

If I do the following code...

var Obj1 = new Table1();
Obj1.Name = "hello"
TestDBEntities.AddToTable1(Obj1);

var currObj = Table1.Where(o => o.Name.Contains("hello")).FirstOrDefault();

currObj will return null.

But if I do this

var Obj1 = new Table1();
Obj1.Name = "hello"
TestDBEntities.AddToTable1(Obj1);
**TestDBEntitles.SaveChanges();**

var currObj = Table1.Where(o => o.Name.Contains("hello")).FirstOrDefault();

Then currObj will return the first object I created. This is because that object is in the database.

I'm creating a large batch process and I don't want to save everything to the database until the end. However, I have to do checks like make sure a certain object hasn't already been added etc. which require me to reference these objects before they have been saved to the database.

Is it possible to make LINQ queries in Entity Framework that can be aware of objects that are in memory which have not been saved to database.

Diskdrive
  • 18,107
  • 27
  • 101
  • 167

3 Answers3

6

I'm a bit late here... @DavidWicks answer doesn't tell the whole story!

The context does provide a mechanism to query - and it got a lot easier in EF4.1 than 4.0

In 4.1 take a look at http://msdn.microsoft.com/en-us/library/gg696248(v=vs.103).aspx the dbSet.Local property holds all of the local changes for objects (that have not been deleted) in the context, so querying against that is all you need!

Andiih
  • 12,285
  • 10
  • 57
  • 88
  • +1 i wish they would hurry up and finish/improve the docs for 4.1; so hard to find relevant info. – David Wick Jun 19 '11 at 11:09
  • Hi, this is probably a stupid question, I just installed EF4.1 - how do I use this Local property? My "TestDBEntities" class is an ObjectContext where the Local property seems to exist in the DbSet class. Please note, I generated the domain model from the database. – Diskdrive Jun 19 '11 at 13:40
  • http://blogs.msdn.com/b/adonet/archive/2010/12/06/ef-feature-ctp5-model-amp-database-first-with-dbcontext.aspx - Really should've read a book about this before just leaping right into EF4. So you have to generate an EDMX file and then you got to generate another file if you want it in a DbContext? Why didn't they just include the whole thing in one step? – Diskdrive Jun 19 '11 at 13:51
  • Books - checkout Programming Entity Framework by Julia Lerman. The 2nd Edition is EF4 (not 4.1) – Andiih Jun 19 '11 at 17:41
  • Re @stickmans one step question - think of the EDMX as an engine+API. The DbContext is kindof an 3rd party add-on written against the API, if you don't want it, dont use it, if a different one better meets your needs, use that etc... – Andiih Jun 20 '11 at 11:53
3

Add the created and unsaved objects to a List<T> then filter that list with linq like you did above.

EDIT: actually, i stand corrected. It looks like you can specify merge options on the ObjectContext.

TestDBEntities.ObjectStateManager.GetObjectStateEntries(EntityState.Added)
    .Where(o => o.GetType() == typeof(Object1Type) 
           && o => o.Name.Contains("hello"))
    .FirstOrDefault();

the docs.

David Wick
  • 7,055
  • 2
  • 36
  • 38
  • really? so the only way to do this is to keep lists of all my objects in memory and manage it all manually? – Diskdrive Jun 19 '11 at 02:08
  • @david : your thing does work so it's good to at least know there is a solution. I still think it's a little cumbersome. I found another question (http://stackoverflow.com/questions/815586/entity-framework-using-transactions-or-savechangesfalse-and-acceptallchanges) which I might try to implement, although I'm not sure how out of date it is as the SaveChanges overload it uses has been deprecated. – Diskdrive Jun 19 '11 at 02:35
  • @stickman: you can always override `SaveChanges` and handle it however you like. Also, feel free to give me some credit if the answer is correct :)! – David Wick Jun 19 '11 at 02:39
  • @David : Yeah I'm new to EF so I didn't realize there was SaveChanges and AcceptAllChanges so I'm figuring out what the difference is. Looks like there is a way to have some sort of SQL Transaction type thing. – Diskdrive Jun 19 '11 at 02:46
  • Its NOT a transaction - all regular queries hit the database, and ignore local changes, however, EF4.1 provides an easy way to query those local changes - (and EF4.0 provides a more complicated one) – Andiih Jun 19 '11 at 11:03
  • @andiih - I could just wrap a TransactionScope around the entire program . It seems to work actually but my batch takes a long time to process and I don't want to hold up the DB for too long and now I'm learning more about EF4.1, I really want to understand the proper way instead. – Diskdrive Jun 19 '11 at 13:45
  • We are all learning about 4.1 :-) I only know this because I got caught out a few days ago expecting it to be more like a transaction. see https://twitter.com/#!/andiih/status/81274793629978624 – Andiih Jun 19 '11 at 17:39
0

That is only what do you need to do:

    Datacontext.YourTable.Add(entity);
    var x=Datacontext.YourTable.Local;

With .Local get the local state of the entity dbset :)

Richard Aguirre
  • 543
  • 6
  • 14