2015-08-20 1 views
8

Я немного новичок, когда он приходит в Entity Framework 6 из старого стиля ADO.NET, поэтому несите меня здесь.Исключение Entity Framework 6: «Контекст не может использоваться во время создания модели»

Я пытаюсь создать новый проект WPF MVVM, а также несколько WinForms, которые будут использовать только прямо DBContext без привязки данных с EF 6.

с помощью Visual Studio 2013 Entity мастера рамочного, я создал сначала с помощью кода, с помощью обратной инженерии текущей базы данных на нашем бизнес-сервере. Затем я отделил классы модели данных из контекста

Это DbContext код:

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); 
     } 
    } 
} 

Я отделил классы данных в отдельном пространстве имен, например:

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;  } 
    } 
} 

остальные классы находятся в аналогичном стиле, но при использовании ограничения внешнего ключа у него есть что-то вроде этого:

public virtual OrderDetail OrderDetail { get; set; } 

Поскольку в нашем маленьком мире он будет вращаться вокруг Орденов.

И 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> 

Так что, когда я делаю это:

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

Исключение брошено:

контекст не может быть использована в то время как модель создается. Это исключение может быть выбрано, если контекст используется внутри метода OnModelCreating или если один и тот же экземпляр контекста обращается к нескольким потокам одновременно. Обратите внимание, что члены экземпляра DbContext и связанные классы не гарантируют безопасность потоков.

Я собираюсь сходить с ума, пытаясь выяснить, что я могу сделать, и я читал, что, возможно, может помочь фабрика задач, так как я могу использовать ее для получения данных из каждой таблицы так что я могу заполнить списки?

У вас есть другая альтернатива или обходное решение, которое я могу использовать?

EDIT: Вот полный StackTrace по запросу (по 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) 
+0

в идеале вам нужно обернуть контекст в использовании заявления: используя (вар контекст = новый MyDataContext() { вара list1 = context.JournalEntryDatas.ToList(); var list2 = context.OrderHistories.ToList(); } Но я не вижу, чтобы это было причиной. – Andez

+0

Я предполагаю, что модель действительна, включая отношения, определенные в построителе модели? Вы пробовали начать с меньшего количества классов моделей (скажем, два) и отработать оттуда? Кроме того, у вас есть стек вызовов исключения? Также проверьте, что у вас нет асинхронных вызовов, происходящих в коде, которые могут быть опущены из вашего сообщения. – Andez

+1

, как правило, это происходит с многопоточным кодом и доступом к контексту, в то время как его первый экземпляр и уже построил модель из другого потока. У вас только три линии? – kmcc049

ответ

0

Я думаю, что это, возможно, придется делать с внешним ключом создания в onModelCreating. Согласно documentation, метод onMethodCreating "вызывается, когда модель для производного контекста была инициализирована, но до того, как модель была заблокирована и использована для инициализации контекста".

Кроме того, если вы используете EF6, вы можете объявить отношения в своих объектах домена, вместо того, чтобы вручную объявлять отношения самостоятельно. Я вижу, что у вас уже есть отношения, объявленные в вашей модели; удалите это и посмотрите, что произойдет. См. here для получения дополнительной информации о настройке отношений «один ко многим».

+0

Привет, Иван, спасибо за ответ! Я пробовал это раньше и удалял, или просто поручил это, и я все еще получаю ту же ошибку. –

+0

Я должен был упомянуть, что я вытащил некоторые строки внутри OnModelingCreating, чтобы убедиться, что это был код, вызывающий проблему, но не радость. –

0

Это может быть строка подключения или другая проблема, связанная с подключением, например, база данных, не существующая или аутентификация.

Возможно, вам также потребуется обновить базу данных.

С NuGet менеджер пакетов консоли:

Update-Database 

"Context cannot be used while the model is being created" exception with ASP.NET Identity

Entity Framework - The context cannot be used while the model is being created

The context cannot be used while the model is being created

0

Вы сказали, что (были) новые в рамках сущности, поэтому, возможно, стоит отметить что DbContexts не должны использоваться совместно и повторно использоваться. Обычно вы хотите создавать, использовать и размещать DbContext в одной единице работы.

Другими словами, вы не должны «делиться» с DbContext (например, создавать только один при запуске и использовать его в нескольких местах и ​​т. Д. Вы упомянули о попытке создать «поточно-безопасную оболочку» - вы определенно не должен пытаться получить к нему доступ из нескольких потоков (каждая операция будет иметь свой собственный DbContext)

Смежные вопросы