I've read that in Entity Framework Core HiLo pattern "Hi" part is managed by database and "Lo" part is managed by Entity Framework in memory.
How does Entity Framework generate "Lo" part without round-trip to database?
How persist the "Lo" value between requests?
And most important, is this pattern thread safety?
Thanks!
The HiLo generator works by occasionally reserving a block of IDs on the server then using IDs from that block on the client as needed. You only need to hit the database when reserving the block, so if your block size is 100, you'll round-trip every 100 IDs.
Yes, it's safe to have multiple contexts assigning IDs concurrently since the block is atomically assigned by the database server. Each DbContext instance will have its own block.
Related
I just found some really strange behaviour which turns out it is not so strange at all.
My select statement (query from database) worked only the first time. The second time, query from database was cached.
Inside Hub method I read something from database every 10 seconds and return result to all connected clients. But if some API change this data, Hub context does not read actual data.
In this thread I found this:
When you use EF it by default loads each entity only once per context. The first query creates entity instance and stores it internally. Any subsequent query which requires entity with the same key returns this stored instance. If values in the data store changed you still receive the entity with values from the initial query. This is called Identity map pattern. You can force the object context to reload the entity but it will reload a single shared instance.
So my question is how to properly use EFCore inside SignalR Core hub method?
I could use AsNoTracking, but I would like to use some global setting. Developer can easily forget to add AsNoTracking and this could mean serving outdated data to user.
I would like to write some code in my BaseHub class which will tell context do not track data. If I change entity properties, SaveChanges should update data. Can this be achieved? It is hard to think all the time to add AsNoTracking when querying from hub method.
I would like to write some code in my BaseHub class which will tell context do not track data.
The default query tracking behavior is controlled by the ChangeTracker.QueryTrackingBehavior property with default value of TrackAll (i.e. tracking).
You can change it to NoTracking and then use AsTracking() for queries that need tracking. It's a matter of which are more commonly needed.
If I change entity properties, SaveChanges should update data.
This is not possible if the entity is not tracked.
If you actually want tracking queries with "database wins" strategy, I'm afraid it's not possible currently in EF Core. I think EF6 object context services had an option for specifying the "client wins" vs "database wins" strategy, but EF Core currently does not provide such control and always implements "client wins" strategy.
Our system manages N data dases which all of them share the same tables (standard tables), but in addition each data base has its own specific tables too.
The modules which access the standard tables are programmed in the core. To access specefic tables we load assemblies by reflection in which there are a specific assembly for every data base.
How can we solve an operation which works with standard tables (core programming) and specific ones (due to reflection) in which the whole operation is in a transaction?.
We can not use 2 EF context, due to we are not able to use distributed transaction
Thank you in advance
If you use the same connection string for both DbContexts, you do not need a distributed transaction with EF6, as you can pass a SqlTransaction that you own to each DbContext - see https://msdn.microsoft.com/en-us/library/dn456843(v=vs.113).aspx under the "Passing an existing transaction to the context" heading
My C# application uses EF and calls min() on an int column to get the 'next' number in a sequence of numbers from a database table. The database table already has the next X numbers ready to go and my EF code just needs to get the 'next' one and after getting this number, the code then deletes that entry so the next request gets the following one etc. With one instance of the application all is fine, but with multiple users this leads to concurrency issues. Is there a design pattern for getting this next min() value in a serial fashion for all users, without resorting to a stored procedure? I'm using a mix of EF4.5 and EF5.
Thanks, Pete
Firstly, you can add an timestamp type column into your table and on Entity Framework property window set the concurrency mode to Fixed.
Doing that you enable optimistic concurrency check on the table. If there is another data context tries to interrupt your update, it will generate an excepton.
Check this link: http://blogs.msdn.com/b/alexj/archive/2009/05/20/tip-19-how-to-use-optimistic-concurrency-in-the-entity-framework.aspx?Redirected=true
Alternatively, you can use a TransactionScope object on your select/update logic. You can simply wrap around your code logic with a TransactionScope logic and everything within the scope will be enforced by the transaction.
Check this link for more information:
TransactionScope vs Transaction in LINQ to SQL
Assuming I am never writing with EF, will never call SaveChanges for example, Is EF safe for concurrent reads from the same ObjectContext?
It may still be initialising a database connection and reading new objects, or updating existing objects (or deleting!) but it won't be writing anything to the db, so no transactions (I assume).
Thanks
ObjectContext and related EF classes are not thread safe so don't use them for concurrent operations. If you need to run concurrent data access use a new context for every thread.
I am writing an application that will move data from one database to another Using JPA EntityManager API. My questions are : 1. Can i use multiple entity managers in a single transaction? 2. Can i read an entity from one database and persist it in the other? what are the issues that am likely to encounter?
Can I use multiple entity managers in a single transaction?
Yes, using JTA. I'm not sure you need a global transaction in your case though. Are you really moving or copying entities from one DB to the other? In the later case, you could use two transactions sequentially.
Can I read an entity from one database and persist it in the other?
Assuming they have the same structure and you don't have any conflicting PK, it should be possible to read an entity using a first entity manager, detach it and then merge it using another entity manager. If you have possible PK conflicts, you'll have to use a DIY approach (vs a simple merge).