实体类型 < type > 不是当前上下文的模型的一部分

我正在进入实体框架,但我不确定是否遗漏了代码优先方法中的一个关键点。

我使用了一个基于 https://genericunitofworkandrepositories.codeplex.com/代码的通用存储库模式,并创建了我的实体。

但是,当我试图访问或修改实体时,会遇到以下情况:

System.InvalidOperationException: 实体类型 Estate 不是部分 模型的当前上下文。

当我试图从存储库中访问它时,就会发生这种情况:

public virtual void Insert(TEntity entity)
{
((IObjectState)entity).ObjectState = ObjectState.Added;
_dbSet.Attach(entity); // <-- The error occurs here
_context.SyncObjectState(entity);
}

数据库(./SQLEXPRESS)创建得很好,但是实体(表)在启动时没有创建。

我想知道是否需要显式设置实体的映射?EF 自己做不到吗?

我的实体是:

public class Estate : EntityBase
{
public int EstateId { get; set; }
public string Name { get; set; }
}

我的背景是这样的:

public partial class DimensionWebDbContext : DbContextBase // DbContextBase inherits DbContext
{
public DimensionWebDbContext() :
base("DimensionWebContext")
{
Database.SetInitializer<DimensionWebDbContext>(new CreateDatabaseIfNotExists<DimensionWebDbContext>());
Configuration.ProxyCreationEnabled = false;
}


public new IDbSet<T> Set<T>() where T : class
{
return base.Set<T>();
}


}

发生这种错误的具体原因是什么?我试过在没有任何帮助的情况下启用迁移和自动迁移。

279368 次浏览

把这个放到你自定义的 DbContext类中:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Estate>().ToTable("Estate");
}

如果您的表没有在启动时创建,这就是原因。您需要在 OnModelCreate 方法覆盖中告诉 DbContext 关于它们的信息。

您可以在这里执行定制的每个实体映射,也可以将它们分成单独的 EntityTypeConfiguration<T>类。

显然,这个错误非常普遍,可能有很多原因。在我的示例中,如下所示: 由 .edmx生成的连接字符串(在 Web.config 中)无效。经过将近一天的尝试,我将连接字符串从 EF 字符串更改为 ADO.NET 字符串。这解决了我的问题。

例如,EF 字符串看起来像这样:

<connectionStrings>
<add name="BlogContext"
connectionString="metadata=res://*/BloggingModel.csdl|
res://*/BloggingModel.ssdl|
res://*/BloggingModel.msl;
provider=System.Data.SqlClient
provider connection string=
&quot;data source=(localdb)\v11.0;
initial catalog=Blogging;
integrated security=True;
multipleactiveresultsets=True;&quot;"
providerName="System.Data.EntityClient" />
</connectionStrings>

ADO.NET 字符串如下所示:

<connectionStrings>
<add name="BlogContext"
providerName="System.Data.SqlClient"
connectionString="Server=.\SQLEXPRESS;Database=Blogging;
Integrated Security=True;"/>
</connectionStrings>

资料来源: http://msdn.microsoft.com/nl-nl/data/jj556606.aspx

问题可能出现在连接字符串中。确保您的连接字符串是针对 SqlClient 提供程序的,没有与 EntityFramework 相关的元数据内容。

听起来很明显,但是要确保你没有明确忽略这个类型:

modelBuilder.Ignore<MyType>();

您可以尝试从模型中删除该表并再次添加它。可以通过打开。来自解决方案资源管理器的 edmx 文件。

步骤:

  1. 双击解决方案资源管理器中的. edmx 文件
  2. 右键单击要删除的表头,然后选择“ Delete from Model”
  3. 现在再次右键单击工作区域并选择“ Update Model from Database. .”
  4. 再次从表列表中添加表
  5. 清理并构建解决方案

对我来说,问题在于我没有在实体框架的上下文中将实体类包含在我的 db 集中。

public DbSet<ModelName> ModelName { get; set; }

当数据库中的现有表不能适当地映射到代码优先模型时,我发现了这个错误。具体来说,我在数据库表中有一个 char (1) ,在 C # 中有一个 char。将模型更改为字符串解决了这个问题。

添加到配置中的实体映射(即使是空的)将导致实体类型成为上下文的一部分。我们有一个与其他实体没有关系的实体,它用一个空映射固定。

另一件需要检查连接字符串的事情是模型名。我用了两个实体模型,首先是 DB。在配置中,我复制了一个实体连接,重命名了它,并更改了连接字符串部分。我没有改变的是模型名称,因此当实体模型正确生成时,当上下文被启动时,EF 正在为实体寻找错误的模型。

写下来看起来很明显,但还有四个小时我就回不来了。

如果您首先尝试 DB,那么请确保您的表具有 主键

对我来说,问题在于我使用了由 ADO.Net Model (。Edmx).更改连接字符串解决了我的问题。

如果您使用的持久化模型缓存由于这样或那样的原因已经过期,也可能发生这种情况。如果上下文已被缓存到文件系统上的 EDMX 文件(通过 DbConfiguration)。(SetModelStore) ,则将永远不会调用 OnModelCreate,因为将使用缓存版本。因此,如果缓存存储中缺少一个实体,那么即使连接字符串是正确的,表存在于数据库中,并且该实体在 DbContext 中设置正确,您也会得到上述错误。

我的问题通过更新连接字符串的元数据部分得到了解决。显然它指错了方向。Csdl/.Ssdl/.Msl 参考文献。

Visual Studio 2019 似乎给我带来了这个问题,我在2017年通过再次生成 edmx 模型修复了这个问题。

信息很清楚,但我一开始没明白..。

我在同一个方法中处理两个实体框架 DB 上下文 sysContextshardContext

我修改过的更新的实体来自一个上下文,但是我尝试将它保存到另一个上下文,如下所示:

invite.uid = user.uid;


sysContext.Entry(invite).State = EntityState.Modified;


sysContext.SaveChanges(); // Got the exception here

但正确的版本应该是这样的:

invite.uid = user.uid;


shardContext.Entry(invite).State = EntityState.Modified;


shardContext.SaveChanges();

在将实体传递到正确的上下文之后,这个错误消失了。

删除. edmx 文件并再次添加它。 特别是,如果您已经升级了实体框架。

我在尝试更新一系列值时遇到了同样的问题。

这种方法行不通

  _dbSet.AttachRange(entity);
_context.Entry(entity).State = EntityState.Modified;
await _context.SaveChangesAsync().ConfigureAwait(false);

添加 UpdateRange 方法并删除附加和输入之后,一切正常

  _dbSet.UpdateRange(entity);
await _context.SaveChangesAsync().ConfigureAwait(false);

对我来说,这是因为我重命名了实体类。当我回滚它时,它是 OK 的。

可能是愚蠢的,但如果你只得到这个错误的一些表,不要忘记清理您的项目和重建(可以节省很多时间)

我有这个

using (var context = new ATImporterContext(DBConnection))
{
if (GetID(entity).Equals(0))
{
context.Set<T>().Add(entity);
}
else
{
int val = GetID(entity);
var entry = GetEntryAsync(context, GetID(entity)).ConfigureAwait(false);
context.Entry(entry).CurrentValues.SetValues(entity);


}
    

await context.SaveChangesAsync().ConfigureAwait(false);
}

这是在一个异步方法中,但是我忘记在 GetEntryAsync 之前放置 wait,所以我得到了同样的错误..。

确保已将 映射类设置为指向 SQL 表

我也遇到过同样的问题,在我的例子中,我得到这个错误消息的原因是我的类文件中的属性标识符与数据库中定义的标识符不匹配,例如,我写了一个标识符,开头是大写字母,而在数据库中是小写字母。

在使用 Web 部署发布我的项目之后,我遇到了这个问题。之所以会发生这种情况,是因为发布配置文件的连接字符串中的元数据与项目中的连接字符串不同,因为我出于某种原因删除了 edmx,并使用不同的 Name 重新添加了它。为了修复它,我必须删除发布配置文件并重新部署,以便元数据与名称匹配。

使用从数据库(First Database)创建的模型,不可能替换连接字符串(使用元数据和 provision erName = “ System。百科。EntityClient”,来自 EDMX)。

我发现的唯一可能性是创建另一个使用 SQL 连接的上下文(provision erName = “ System.Data.SqlClient”)

<connectionStrings>
<add name="DefaultConnection" providerName="System.Data.SqlClient"  connectionString="Max Pool Size=10000;Pooling=true;Data Source=MyIpServer;Initial Catalog=myDatabase;Persist Security Info=True;User ID=MyUser;Password=MyPassword;TrustServerCertificate=False" />
<add name="Entities" providerName="System.Data.EntityClient"  connectionString="metadata=res://*/Datos.MyModel.csdl|res://*/Datos.MyModel.ssdl|res://*/Datos.MyModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;Max Pool Size=10000;Pooling=true;data source=MyIpServer;initial catalog=myDatabase;persist security info=True;user id=MyUser;password=MyPassword;trustservercertificate=False;MultipleActiveResultSets=True;App=EntityFramework&quot;" />
</connectionStrings>

使用两个上下文选项,使用 Identity:

public partial class ContextWithUsers : IdentityDbContext<MyUser>
{
public ContextWithUsers() : base("name=DefaultConnection")
{
}
}


public class MyUser : IdentityUser
{
// aditional table user data
//public virtual MyUserInfo MyUserInfo { get; set; }
}

正常情况:

public partial class ContextWithoutUsers : DbContext
{
public ContextWithoutUsers () : base("name=Entities")
{
}
}

这个解决方案是可行的,但是... ... 为什么不可能在 First Database 模型 + Identity 中使用相同的上下文呢?

注意1: 如果强制更改连接字符串,则显示:

系统。百科。实体。基础设施。异常: “上下文正在代码优先模式下使用,代码是从一个 EDMX 文件生成的,用于数据库优先或模型优先开发。这不会正常工作。若要修复此问题,请不要删除引发此异常的代码行。如果您希望使用 Database First 或 Model First,那么请确保 Entity Framework 连接字符串包含在启动项目的 app.config 或 web.config 中。如果您正在创建自己的 DbConnection,那么请确保它是一个 EntityConnection,而不是其他类型的 DbConnection,并且将它传递给接受 DbConnection 的基本 DbContext 构造函数之一。要了解更多关于代码优先、数据库优先和模型优先的信息,请参阅实体框架文档: http://go.microsoft.com/fwlink/?LinkId=394715'

注2: 带 EDMX + Data 和 ASP.NET webform 项目的外部类库