Je suis un peu nouveau en ce qui concerne Entity Framework 6 de l'ancien style de ADO.NET, alors tenez compte de moi.
J'essaie de créer un nouveau projet MVF WPF ainsi que quelques WinForms qui utiliseront directement DBContext
sans liaison de données avec l'EF 6.
À l'aide de l'assistant d'infrastructure Visual Studio 2013 Entity, j'ai créé un code d'abord en procédant à l'ingénierie inverse d'une base de données actuelle sur notre serveur d'entreprise. J'ai ensuite séparé les classes de modèle de données du contexte
C'est le code 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);
}
}
}
J'ai séparé les classes de données dans un espace de noms séparé, par exemple:
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; }
}
}
Les autres classes ont un style similaire, mais si vous utilisez la contrainte de clé étrangère, vous obtenez quelque chose comme ceci:
public virtual OrderDetail OrderDetail { get; set; }
puisque dans notre petit monde, cela tournera autour des ordres.
Et le 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>
Alors quand je fais ça:
var context = New MyDataContext();
var list1 = context.JournalEntryDatas.ToList();
var list2 = context.OrderHistories.ToList();
Une exception est levée:
Le contexte ne peut pas être utilisé pendant la création du modèle. Ce Une exception peut être levée si le contexte est utilisé dans le fichier
OnModelCreating
ou si la même instance de contexte est accédée par plusieurs threads simultanément. Notez que les membres d'instance deDbContext
et les classes associées ne sont pas garanties d'être thread-safe.
Je ne sais pas quoi que ce soit en essayant de comprendre ce que je peux faire, et j'ai lu que faire une usine de tâches pourrait peut-être aider, alors comment puis-je l'utiliser pour obtenir les données de chaque tableau afin de pouvoir remplir les listes ?
OU existe-t-il une autre solution ou solution de contournement que je puisse utiliser?
EDIT: Voici la pile complète comme demandé (par 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)
Vous avez dit que vous (étiez) nouveau dans le cadre d'entité, alors peut-être qu'il vaut la peine de souligner que DbContext
s n'est pas censé être partagé et réutilisé. Généralement, vous souhaiterez créer, utiliser et disposer d'une DbContext
au sein d'une même unité de travail.
En d'autres termes, vous ne devriez pas "partager" la DbContext
(par exemple, en créer une au démarrage et l'utiliser à plusieurs endroits, etc. essayant d'y accéder à partir de plusieurs threads (chaque opération aurait son propre DbContext)
Cela peut être la chaîne de connexion ou un autre problème lié à la connexion, la base de données inexistante ou l'authentification par exemple.
Vous devrez peut-être également mettre à jour la base de données.
À partir de la console du gestionnaire de paquets Nuget:
Update-Database
Entity Framework - Le contexte ne peut pas être utilisé pendant la création du modèle
Le contexte ne peut pas être utilisé pendant la création du modèle
Je pense que cela pourrait avoir à voir avec la création de clé étrangère dans onModelCreating. Selon la documentation , la méthode onMethodCreating "est appelée lorsque le modèle d'un contexte dérivé a été initialisé, mais avant que le modèle ait été verrouillé et utilisé pour initialiser le contexte".
De plus, si vous utilisez EF6, vous pouvez déclarer la relation dans vos objets de domaine au lieu de devoir la déclarer manuellement vous-même. Je constate que vous avez déjà les relations déclarées dans votre modèle; retirez cela et voyez ce qui se passe. Voir ici pour plus d'informations sur la configuration de relations un à plusieurs.