Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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)
like image 216
Steve Brother Avatar asked Aug 20 '15 21:08

Steve Brother


1 Answers

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)

like image 124
Mark Sowul Avatar answered Oct 02 '22 06:10

Mark Sowul