Design Meeting Notes - August 23, 2012
Make ObjectContext implement IObjectContextAdapter
This was requested in the CodePlex discussion as a way to provide a common interface for both DbContext and ObjectContext from which the ObjectContext can be obtained in a common way. Not super-high value, but very easy to do and doesn’t impact the DbContext
API at all.
Decision: We will create a work item for this and accept the contribution if it is made. (http://entityframework.codeplex.com/workitem/473)
Enable migrating multiple DbContexts in a single database
- Problem: HistoryTable is single context
- Solution? - Allow a single history table to store data for multiple contexts.
- Hard to differentiate rows – can’t really use context type name as not refactor safe.
- Can we allow the user to configure the tenant name, possibly with the context name as the initial default?
- We could get the container name from the model, but this doesn’t work for automatic migrations.
- Decision: For now we will go with multiple tables and will revisit this if necessary based on feedback.
- Solution? – Allow multiple history tables.
- Can already do this with HasDefaultSchema()
- But should also be possible via renaming.
- Exploratory testing needed: It seems like we have the correct building blocks but we may need to add sugar to make it easy for app developers to have multiple contexts
- Consider the case where universal providers has a context/migrations; this should be transparent to the app developer
- Consider the case where all the user wants is multiple contexts without any other changes—should be easy, possibly even with an F5 experience without a migrations configuration
History table customization
- Introduce IHistoryContextFactory
- Registered via DbConfiguration
- Keyed singleton (key is type of MigrationsConfiguration)
- Subclass HistoryContext to customize mapping in OnModelCreating.
- Also useful for provider customization.
- But probably need to incorporate provider name into resolver key.
- Exploratory testing needed: Is it possible to change the HistoryRow entity itself? For example adding a new primary key?
- This can be useful for some backends where the current MigrationID is not an ideal key
- Could this be done with table-splitting combined with overriding SaveChanges?
- It would be great if the migration provider could hook into the history table configuration
- So, for example, just installing the provider makes the history table work without any additional intervention
Migration code file organization within project
- Could try and support multiple sets within single Migrations folder (namespace).
- But likely not worth it given:
- Should already be able to have multiple “Migrations” folders in a single project. (via –ConfigurationTypeName in PS)
- Seems to be a bug when adding migrations – they all go into the same folder
- Should also accept unqualified config type name as shortcut.
- Can also use multiple projects as a way to organize things.
- So, keep it simple and listen for feedback.
- Exploratory testing needed: What’s the experience like with multiple folders?
Previous versions of the designer assemblies used version numbers based on Visual Studio versions (10.1, 11.1, etc.). What should we do with the open-source assemblies?
- Change the strong names of the assemblies?
- This allows us to version independently starting where appropriate without clashes
- Decision: will do this, but need to check for any external dependencies on the assemblies
- Sematic versioning: Yes
- Where to start? 1.0? 6.0?
- Decision: At least initially, start with version that aligns with runtime release (e.g. 6.0)
- Current plan is for new designer to uninstall and replace old designer
- Could decide to keep the old and only use the new for EF6
- Will investigate this if it becomes problematic to support old EDMX/code gen/etc from new designer
- Should the new designer support VS 2010 as well as VS 2012?
- For now we will focus on VS 2012
DbContext/ObjectContext are not thread safe and making them generally so is prohibitively expensive for the common scenario of short-lived context instances. However, inappropriate use of async support now makes it easy to access the same context concurrently
without it being obvious that this is happening—just start using the context again after starting an async task before waiting for the async task to complete.
Can we help protect against this by adding checks that the context is being used while an async task is in progress?
- Could add a flag that is set whenever an async task is in progress and not reset until it completes
- Not possible to check this flag in all cases (not available) but could possibly be done in some cases (e.g. SaveChanges)
- Need to be sure that whatever synchronization mechanism is used cannot result in false exceptions
- If a task completes and sets the flag but another thread reads a stale version of the flag and throws this would be a serious problem
- Need to also make sure that perf of doing the check is not prohibitive