Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there any way I can make Effort.EF6 work with a null database initialiser? #45

Closed
JonPSmith opened this issue Aug 31, 2016 · 7 comments
Assignees

Comments

@JonPSmith
Copy link

Hi,

I am using your excellent Effort.EF6 package in my Unit Tests. I handle database migrations myself and use a null database initialiser to stop EF checking the migrations at the start.

However, if I called Database.SetInitializer<MyDbContext>(null) in a Unit Test class (I am xUnit) then Effort throws an exception (below) and shows the message Effort.Exceptions.EffortException. Database has not been initialized.

Obviously this is an edge case, but if you have any ideas on how I might get round it I would appreciate it.

Full Exception information

System.Data.Entity.Core.EntityCommandExecutionException
An error occurred while executing the command definition. See the inner exception for details.
   at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
   at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext context, ObjectParameterCollection parameterValues)
   at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
   at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__5()
   at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
   at System.Data.Entity.Core.Objects.ObjectQuery`1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0()
   at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
   at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
   at Tests.UnitTests.Group01Tests.EffortEF6.TestEffortUsage.CreateDbContextViaEffort() in C:\Users\Jon\documents\visual studio 2015\Projects\OilAndGasWeb\Tests\UnitTests\Group01Tests\EffortEF6\TestEffortUsage.cs:line 22

Effort.Exceptions.EffortException
Database has not been initialized.

If using CodeFirst try to add the following line:
context.Database.CreateIfNotExists()
   at Effort.Internal.DbManagement.DbContainer.get_Internal()
   at Effort.Internal.DbManagement.DbContainer.GetTable(String name)
   at Effort.Internal.DbCommandTreeTransformation.TransformVisitor.Visit(DbScanExpression expression)
   at Effort.Internal.DbCommandTreeTransformation.TransformVisitor.Visit(DbGroupByExpression expression)
   at Effort.Internal.DbCommandTreeTransformation.TransformVisitor.Visit(DbProjectExpression expression)
   at Effort.Internal.CommandActions.QueryCommandAction.ExecuteDataReader(ActionContext context)
   at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
   at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext)
   at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
@tamasflamich
Copy link
Collaborator

Hi JonPSmith - Sorry for the late response. This shouldn't be a problem as Effort is not able to work when migrations is enabled, the suggested workaround is indeed to disable the initialiser.

What does happen if you indeed initialize your db explicitly?

@JonPSmith
Copy link
Author

Hi @tamasflamich,

The problem is if I call a null initialiser, e.g. Database.SetInitializer<MyDbContext>(null) then the next time Effort.EF6 accesses the database I get the exception I detailed in the first post above. I do this because some tests do access a real database directly and I want to make sure it doesn't look for migrations.

I have no migrations set on the database so its not that. I'm pretty sure Effort.EF6 doesn't support the calling of a null initialiser.

It would be great to have that fixed, but as a creator of a number of open-source libraries and working I know that time is limited. If you do get a chance to look at this/fix it then let me know.

@JasonMisavage
Copy link

@JonPSmith, I had a similar problem. I solved it by registering a System.Data.Entity.NullDatabaseInitializer<T> in my Dependency Injection container (Ninject, in my case) for production and the default System.Data.Entity.CreateDatabaseIfNotExists<T> initializer for unit tests. Then in the constructor of my EF context I just select whatever was registered, like so:
Database.SetInitializer(DIContainer.Get<IDatabaseInitializer<MyDbContext>>());

My use case isn't quite the same as yours since I don't have to think about migrations. But, you might consider a CustomInitializer for the tests that does the "Database.CreateIfNotExists()" line recommended in the error message and ignores any migration steps that the default initializer would try to do.

@JonathanMagnan JonathanMagnan self-assigned this Sep 6, 2018
@screaney
Copy link

I'm having a similar issue, except my context is database first but with FluentAPI, so a hybrid model. My Context constructor always runs Database.SetInitializer<Context>(null);. That being the case, shouldn't Effort also apply this? I've tried putting it in my constructor, as well as in the unit test explicitly, however, I always get

Effort.Exceptions.EffortException: Database has not been initialized.

@JonathanMagnan
Copy link
Member

Hello @screaney ,

We will try to look at this issue next week,

Best Regards,

Jonathan

@michaelfoidl
Copy link

Any news on this?

I'm having the same issue, although calling context.Database.CreateIfNotExists() is not an option for me, because I use a custom initialization infrastructure.

@JonathanMagnan
Copy link
Member

Hello @michaelfoidl ,

Unfortunately no, we never found a solution.

The Effort in-memory database doesn't exist by default unlike your real database, so it currently requires the memory database to be created.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

6 participants