当它从旧式的ADO.NET进入实体框架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
的实例成员 和相关的类不保证是线程安全的。
我在这里努力想弄清楚我能做些什么,而且我一直在读,也许做一个任务工厂可以提供帮助,那么我怎样才能用它来获取每个数据表,所以我可以填充列表?
OR是否可以使用其他替代方法或解决方法?
编辑:这是所要求的完整堆栈跟踪(由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 :(得分:1)
你说你是实体框架的新手,所以也许值得指出DbContext
不应该被共享和重用。通常,您需要在单个工作单元内创建,使用和处置DbContext
。
换句话说,你不应该“共享”DbContext
(例如在启动时只创建一个并在多个地方使用它等等。你提到尝试创建一个“线程安全的包装器” - - 你绝对不应该尝试从多个线程访问它(每个操作都有自己的DbContext)
答案 1 :(得分:0)
我认为它可能与onModelCreating中的外键创建有关。根据{{3}},onMethodCreating方法&#34;在初始化派生上下文的模型时,但在模型被锁定并用于初始化上下文之前调用。&#34;
此外,如果您使用的是EF6,则可以在域对象中声明关系,而不必亲自手动声明关系。我看到你已经在你的模型中宣布了关系;删除它,看看会发生什么。有关配置一对多关系的详细信息,请参阅documentation。
答案 2 :(得分: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