I am new to Entity Framework, so forgive me if the question seems basic. I am wondering, is it better to save the context object created by Entity Framework to use it over the application, or I should create a new context object each time I want to access/modify the database?
To formulate the question differently, will there by any performance problems if I create the context object too frequently? Or will there by any database issues (e.g. locking the database) if I keep the context object alive over the life time of the application?
Both EF, and Linq2SQL contexts are designed for a short lifetime.
If you are serving web pages, usually the best practice is use one context per HTTP request.
But i think this applies to other ORMs as well. All do use some sort of caching, and object change tracking that can result is weird bugs if the context lives for too long, or shared between requests.
Edit: things can be different if you are writing a thick client app.
Related
There is no shortage of tutorials on coredata, or questions here on SO about how to get started with coredata, or how to use specific parts.
My question is higher level - how should a larger project be architected with coredata?
Should the project keep most of the functions that deal with managed
objects in a single class?
Should the functions that deal with the
methods be static (I suppose they are called 'class methods') or
instance methods?
Is it ok to pass managed objects into class
methods from different threads? what about if I also supply a
context to the method?
Should I only be doing a single fetch for each entity when the app starts, then doing all of my searches and inserts against the context, or grabbing smaller sets of data from a fetch request as I need it?
As far as the blogosphere goes, it seems like the coredata architectures are the wild west - every man for themselves. Any good design patterns here to follow?
True, although some of you questions are really based on personal preference. I for one will never use a sigleton.
NO and YES. Yes on class to keep the connection to the context and no every controller will request its own data.
Using class methods requires you to either pass the context around or store it in a static. Using a static can cause problems if you need to change the context.
No, each thread should have it's now context. Core Data is not thread save.
To save memory only fetch what is needed, no sense in fetching everything at once.
I would suggest using NSFecthResultsController for filling things like table views.
If you are fetching data and storing it in core data I can really suggest using a separate context for inserting. Cocoanetics has a great article about multiple context setup.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I need some help in making a design choice for my application. It’s a fairly straightforward web application, definitely not enterprise class or enterprise-anything.
The architecture is standard MVC 5 / EF 6 / C# ASP.NET, and the pages talk to a back-end database that’s in SQL server, and all the tables have corresponding entity objects generated from VS 2013 using the EF designer and I don’t see that changing anytime in the near future. Therefore creating super abstract “what if my database changes” etc. separations is possibly pointless. I am a one-man operation so we're not talking huge teams etc.
What I want is a clean way to do CRUD and query operations on my database, using DbContext and LINQ operations – but I’m not good with database related code design. Here are my approaches
1. Static class with methods - Should I create a static class (my DAL) that holds my datacontext and then provide functions that controllers can call directly
e.g. MyStaticDBLib.GetCustomerById(id)
but this poses problems when we try to update records from disconnected instances (i.e. I create an object that from a JSON response and need to ‘update’ my table). The good thing is I can centralize my operations in a Lib or DAL file. This is also quickly getting complicated and messy, because I can’t create methods for every scenario so I end up with bits of LINQ code in my controllers, and bits handled by these LIB methods
2. Class with context, held in a singleton, and called from controller
MyContext _cx = MyStaticDBLib.GetMyContext(“sessionKey”);
var xx = cx.MyTable.Find(id) ; //and other LINQ operations
This feels a bit messy as my data query code is in my controllers now but at least I have clean context for each session. The other thinking here is LINQ-to-SQL already abstracts the data layer to some extent as long as the entities remain the same (the actual store can change), so why not just do this?
3. Use a generic repository and unitofwork pattern – now we’re getting fancy. I’ve read a bit about this pattern, and there’s so many different advises, including some strongly suggesting that EF6 already builds the repository into its context therefore this is overkill etc. It does feel overkill but need someone here to tell me that given my context
4. Something else? Some other clean way of handling basic database/CRUD
Right now I have the library type approach (1. above) and it's getting increasingly messy. I've read many articles and I'm struggling as there's so many different approaches, but I hope the context I've given can elicit a few responses as to what approach may suit me. I need to keep it simple, and I'm a one-man-operation for the near future.
Absolutely not #1. The context is not thread safe and you certainly wouldn't want it as a static var in a static class. You're just asking for your application to explode.
Option 2 is workable as long as you ensure that your singleton is thread-safe. In other words, it'd be a singleton per-thread, not for the entire application. Otherwise, the same problems with #1 apply.
Option 3 is typical but short-sighted. The repository/unit of work patterns are pretty much replaced by having an ORM. Wrapping Entity Framework in another layer like this only removes many of the benefits of working with Entity Framework while simultaneously increasing the friction involved in developing your application. In other words, it's a lose-lose and completely unnecessary.
So, I'll go with #4. If the app is simple enough, just use your context directly. Employ a DI container to inject your context into the controller and make it request-scoped (new context per request). If the application gets more complicated or you just really, really don't care for having a dependency on Entity Framework, then apply a service pattern, where you expose endpoints for specific datasets your application needs. Inject your context into the service class(es) and then inject your service(s) into your controllers. Hint: your service endpoints should return fully-formed data that has been completely queried from the database (i.e. return lists and similar enumerables, not queryables).
While Chris's answer is a valid approach, another option is to use a very simple concrete repository/service façade. This is where you put all your data access code behind an interface layer, like IUserRepository.GetUsers(), and then in this code you have all your Entity Framework code.
The value here is separation of concerns, added testability (although EF6+ now allows mocking directly, so that's less of an issue) and more importantly, should you decide someday to change your database code, it's all in one place... Without a huge amount of overhead.
It's also a breeze to inject via dependency injection.
I'm developing an iOS application using Core Data. I want to have the persistent store located in a shared location, such as a network drive, so that multiple users can work on the data (at different times i.e. concurrency is not part of the question).
But I also want to offer the ability to work on the data "offline", i.e. by keeping a local persistent store on the iPad. So far, I read that I could do this to some degree by using the persistent store coordinator's migration function, but this seems to imply the old store is then invalidated. Furthermore, I don't necessarily want to move the complete store "offline", but just a part of it: going with the simple "company department" example that Apple offers, I want users to be able to check out one department, along with all the employees associated with that department (and all the attributes associated with each employee). Then, the users can work on the department data locally on their iPad and, some time later, synchronize those changes back to the server's persistent store.
So, what I need is to copy a core data object from one store to another, along with all objects referenced through relationships. And this copy process needs to also ensure that if an object already exists in the target persistent store, that it's overwritten rather than a new object added to the store (I am already giving each object a UID for another reason, so I might be able to re-use the UID).
From all I've seen so far, it looks like there is no simple way to synchronize or copy Core Data persistent stores, is that a fair assessment?
So would I really need to write a piece of code that does the following:
retrieve object "A" through a MOC
retrieve all objects, across all entities, that have a relationship to object "A"
instantiate a new MOC for the target persistent store
for each object retrieved, check the target store if the object exists
if the object exists, overwrite it with the attributes from the object retrieved in steps 1 & 2
if the object doesn't exist, create it and set all attributes as per object retrieved in steps 1 & 2
While it's not the most complicated thing in the world to do, I would've still thought that this requirement for "online / offline editing" is common enough for some standard functionality be available for synchronizing parts of persistent stores?
Your point of views greatly appreciated,
thanks,
da_h-man
I was just half-kidding with the comment above. You really are describing a pretty hard problem - it's very difficult to nail this sort of synchronization, and there's seldom, in any development environment, going to be a turn-key solution that will "just work". I think your pseudo-code description above is a pretty accurate description of what you'll need to do. Although some of the work of traversing the relationships and checking for existing objects can be generalized, you're talking about some potentially complicated exception handling situations - for example, if updating an object, and only 1 out 5 related objects is somehow out of date, do you throw away the update or apply part of it? You say "concurrency" is not a part of the question, but if multiple users can "check out" objects at the same time, unless you plan to have a locking mechanism on those, you would start having conflicts when trying to make updates.
Something to check into are the new features in Core Data for leveraging iCloud - I doubt that's going to help with your problem, but it's generally related.
Since you want to be out on the network with your data, another thing to consider is whether Core Data is the right fit to your problem in general. Since Core Data is very much a technology designed to support the UI and MVC pattern in general, if your data needs are not especially bound to the UI, you might consider another type of DB solution.
If you are in fact leveraging Core Data in significant ways beyond just modeling, in terms of driving your UI, and you want to stick with it, I think you are correct in your analysis: you're going to have to roll your own solution. I think it will be a non-trivial thing to build and test.
An option to consider is CouchDB and an iOS implementation called TouchDB. It would mean adopting more of a document-oriented (JSON) approach to your problem, which may in fact be suitable, based on what you've described.
From what I've seen so far, I reckon the best approach is RestKit. It offers a Core Data wrapper that uses JSON to move data between remote and local stores. I haven't fully tried it yet, but from what the documentation reads, it sounds quite powerful and ideally suited for my needs.
You definetly should check these things:
Parse.com - cloud based data store
PFIncrementalStore https://github.com/sbonami/PFIncrementalStore - subclass of NSIncrementalStore which allows your Persistent Store Coordinator to store data both locally and remotely (on Parse Cloud) at the same time
All this stuff are well-documented. Also Parse.com is going to release iOS local datastore SDK http://blog.parse.com/2014/04/30/take-your-app-offline-with-parse-local-datastore/ wich is going to help keep your data synced.
I work with a senior developer who is a guru .NET architect. We have had many constructive arguments over the last 6+ months and generally I concede defeat in most of our discussions. I have learned stacks from working with him. There is one design problem we are currently in disagreement with, however, and I would like some opinions/suggestions because he hasn't managed to convince me of his position, and I will stick to my guns until someone can give me evidence that I am wrong.
We use Entity Framework 4.0 and we use BOTH persistence aware AND Self Tracked Entities in different models. We started using Self Tracked Entities for tracking changes to Entity Graphs that we serialised/deserialised over the WCF wire to our Silverlight application. It works fantastically. We have also started using Self Tracked Entities for models that we are NOT taking across WCF, but many remain as persistent aware Entities/Models.
My co-worker believes that Entity Frameworks ObjectContext should be kept around for the shortest time possible. He insists that it should only be around for the length of time needed to do a query and the length of time needed to persist something. Any business work done with Entities should be done detached. For each Entity Model we have, we have a query class and a persistent class that are both IDisposable and have the ObjectContext at instance scope and have the query/persistence logic in methods. We use these query/persistence classes in our business logic rather than using the the ObjectContext directly in business logic. When these class instances are constructed so is the ObjectContext and when Disposed, so is the ObjectContext Disposed. These classes are like wrappers around our LINQ operations separating EF from the business logic and assisting with LINQ query re-use.
Now first consider non-Self Tracked Entities:
I understand why he wants this and the desire to not have a long running ObjectContext, but my problem is that he always wants even trivial business logic to be detached from the ObjectContext and the fact that we have a separate query and persistence context under our design means that there is no ObjectContext state tracking of Entities being used in our business logic. For non-Self Tracked Entities this means that if we modify Entities in our business logic we must also set the Modified state of the entities manually prior to persisting. This is a REAL pain when persisting complex graphs with multiple changes. Also I doubt we can do it manually as well as EF does it automatically.
For our Self Tracked Entities this situation is the same because tracking is only turned on when graphs are de-serialised and so when working WITHIN a service where the query was performed, detached from the Context, there is still no tracking with Self-Tracked Entities.
My question is, what is the best practice for Entity Framework use and how should an Entity Framework DAL be designed? How long should the ObjectContext be around? Should business logic always be done detached from the ObjectContext? If so how do we do state tracking when working detached from the ObjectContext? One option I am thinking about is converting ALL of our entities to Self-Tracked Entities and using some graph traversal code to traverse queried graphs and turn tracking on for all of the Entities in the graph so Self Tracking is turned on even when working service side (basically mimicking what happens when the Self-Tracked Entities graph is de-serialised)...
I am not proposing that we keep the ObjectContext around for long periods of time, but working detached between query and persistence and losing the benefits of the ObjectContext state tracking to me seems silly...we are losing one of the great benefits of EntityFramework...
Sorry for long post...any help appreciated.
Microsoft recommends that the ObjectContext be short lived, and my experience has led me to believe that the life-span of an ObjectContext should ideally correlate to the duration of a web-request / user operation.
I made the mistake of trying to use a global, long-lived ObjectContext in a desktop application, and it was a total disaster. If you're going to implement things like caching, under/redo edit semantics, etc. then you should consider a design that uses ViewModel classes which are distinctly seperate from the underlying data entities. Use the EntityFramework to help you construct your Model object graph, then build the ViewModel from that. When you want to save changes, allow your ViewModel Repository to reconnect to the underlying entities, alter their properties and save changes. This allows for a more "cachable", flexible, ORM independant, unit-test-friendly design.
In terms of change tracking, try not to think of it as a cheap "user-made-a-change" mechanism for the UI, but rather as an expensive mechanism for tracking which recently-created entities need to be considered when saving changes.
I am working on a asp.net mvc application.
I have a situation where I have to make many threads which are going to access the database using linqtosql. My question is, will it be fine to leave every thing on linqtosql to maintain the synchronization, because the threads will be accessing the database at the same time. Or I have to write my own code to do that.
If each thread is using its own database context, you will be fine. However, I don't believe the database context object is thread safe. So, it's best to make sure each thread has its own context.
Randy
I'm not sure what kind of synchronization you mean, but databases have been designed such that multiple clients (threads, processes, machines) can access/read/change data at the same time. Linq2Sql is - speaking very simply - just one of the mechanisms to emit SELECT/DELETE/UPDATE statements against the database.
If you are using ASP.NET MVC I would seriously take a look at using S#arp Architecture. It uses nHibernate but provides some scaffolding to make the data layer very easy to create and work with. It uses fluent nhibernate and the AutoPersistenceModel so there is no need to play with XML files for mappings. It also includes a number of very handy to have MVC tools.
Linq2SQL seems to have some pretty serious shortcomings whenever I've tried to do anything remotely sophisticated with it and I would probably only recommend it for very simple scenarios. Perhaps it's just me but I have observed some pretty ugly behaviour with L2S.