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 ofDbContext
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)
You said you (were) new to entity framework, so perhaps it is worth pointing out that DbContext
s 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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With