Entity Framework 6 exception: "The context cannot be used while the model is being created"

24,908

You said you (were) new to entity framework, so perhaps it is worth pointing out that DbContexts are not supposed to be shared and reused. Usually you'll want to create, use, and dispose a DbContext within a single unit of work.

In other words, you shouldn't be "sharing" the DbContext (e.g. creating just one at startup and using it in multiple places, etc. You mentioned trying to create a "thread-safe wrapper" -- you definitely shouldn't be trying to access it from multiple threads (each operation would have its own DbContext)

Share:
24,908
Steve Brother
Author by

Steve Brother

Updated on June 15, 2020

Comments

  • Steve Brother
    Steve Brother almost 4 years

    I'm a bit new when it is coming to Entity Framework 6 from the old style of ADO.NET, so bear with me here.

    I'm trying to create a new WPF MVVM project and also a few WinForms that will use just straight out DBContext without data-binding with the EF 6.

    Using Visual Studio 2013 Entity framework wizard, I created a code-first by reverse engineer a current database on our business server. I then separated the data model classes from the context

    This is the DbContext code:

    namespace EFModels
    {
        public partial class MyDataContext : DbContext
        {
            public MyDataContext () : base("name=MyDataContext")
            {
            }
    
            public virtual DbSet<Calibration> Calibrations { get; set; }
            public virtual DbSet<OrderDetail> OrderDetails { get; set; }
            public virtual DbSet<OrderHistory> OrderHistories { get; set; } 
            public virtual DbSet<WorkDetail> WorkDetails { get; set; }
    
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {   
                modelBuilder.Entity<WorkDetail>()
                        .HasMany(e => e.Calibrations)
                        .WithOptional(e => e.WorkDetail)
                        .HasForeignKey(e => e.WorkID);  
            }
        }
    }
    

    I've separated the data classes in a separate namespace, for example:

    namespace MyDataDomain
    {
        using System;
        using System.Collections.Generic;
        using System.ComponentModel.DataAnnotations;
        using System.ComponentModel.DataAnnotations.Schema;
        using System.Data.Entity.Spatial;
    
        public partial class OrderDetail
        {
            public OrderDetail()
            {
                Calibrations = new HashSet<Calibration>();
                JournalEntryDatas = new HashSet<JournalEntryData>();
                OrderHistories = new HashSet<OrderHistory>();
                WorkDetails = new HashSet<WorkDetail>();
            }
    
            [Key]
            public long OrderID { get; set; }
    
            [StringLength(50)]  
            public string PONumber { get; set; }
    
            [Column(TypeName = "date")]
            public DateTime? Due { get; set; }
    
            [Column(TypeName = "date")]
            public DateTime? OrderDate { get; set; }
    
            [Column(TypeName = "date")]
            public DateTime? ShipDate { get; set; }
    
            [Column(TypeName = "text")]
            public string Comment { get; set; }
    
            public int? EnterByID { get; set; }
    
            public virtual ICollection<Calibration> Calibrations { get; set; }
    
            public virtual ICollection<JournalEntryData> JournalEntryDatas { get; set; }
            public virtual ICollection<OrderHistory> OrderHistories { get; set; }
            public virtual ICollection<WorkDetail> WorkDetails { get; set;      }
        }
    }
    

    The rest of the classes are in similiar style, but when using the foreign key constraint it has something like this:

    public virtual OrderDetail OrderDetail { get; set; }
    

    since in our little world, it will revolve around the Orders.

    And the app.config:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <configSections>
        <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
        <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0,         Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
      </configSections>
      <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
      </startup>
      <connectionStrings>
        <add name="MyDataContext" connectionString="data source=BIZSERVER\SQL2008R2DB;initial catalog=Company;persist security info=True;user id=DaBossMan;password=none_of_your_damn_business;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient"/>
      </connectionStrings>
      <entityFramework>
        <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
          <parameters>
            <parameter value="mssqllocaldb" />
          </parameters>
        </defaultConnectionFactory>
        <providers>
          <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
        </providers>
      </entityFramework>
    </configuration>
    

    So when I do this:

    var context = New MyDataContext();
    var list1 = context.JournalEntryDatas.ToList();
    var list2 = context.OrderHistories.ToList();
    

    An exception is thrown:

    The context cannot be used while the model is being created. This exception may be thrown if the context is used inside the OnModelCreating method or if the same context instance is accessed by multiple threads concurrently. Note that instance members of DbContext and related classes are not guaranteed to be thread safe.

    I'm going nuts here trying to figure out what I can do, and I've been reading that maybe doing a task factory could help, so then how can I use it to get the data from each table so I can populate the lists?

    OR is there another alternative or a workaround that I can use?

    EDIT: Here is the FULL stacktrace as requested (by Andez):

    System.InvalidOperationException was caught
    HResult=-2146233079
    Message=The context cannot be used while the model is being created. This exception may be thrown if the context is used inside the OnModelCreating method or if the same context instance is accessed by multiple threads concurrently. Note that instance members of DbContext and related classes are not guaranteed to be thread safe.
    Source=EntityFramework
    StackTrace:
       at System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
       at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
       at System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()
       at System.Data.Entity.Internal.Linq.InternalSet`1.GetEnumerator()
       at System.Data.Entity.Infrastructure.DbQuery`1.System.Collections.Generic.IEnumerable<TResult>.GetEnumerator()
       at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
       at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
       at MichellControls.JournalDataListView.JournalDataListView_Load(Object sender, EventArgs e) in c:\Users\Steve\Projects\Visual Studio 2013\Projects\MyControls\WinFormControls\JournalDataListView.cs:line 35
    InnerException: 
        // (there wasn't any InnerException)
    
  • Steve Brother
    Steve Brother over 8 years
    Hi Ivan, thanks for the response! I did try that before and removed, or just committed it out, and I'm still getting the same error.
  • Steve Brother
    Steve Brother over 8 years
    I should have mentioned that I took out some lines inside the OnModelingCreating to see if it was offending code that is causing the problem, but no joy.