我正在进入实体框架,但我不确定我是否错过了代码优先方法中的关键点。
我正在使用基于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>();
}
}
是否有任何特定原因导致此错误发生?我尝试过启用迁移并启用自动迁移,但没有任何帮助。
答案 0 :(得分:120)
将其放入您的自定义DbContext
课程中:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Estate>().ToTable("Estate");
}
如果您的表未在启动时创建,这就是原因。您需要在OnModelCreating方法覆盖中告诉DbContext有关它们的信息。
您可以在此处执行自定义按实体映射,也可以将它们分隔为单独的EntityTypeConfiguration<T>
类。
答案 1 :(得分:63)
显然,这个错误很通用,可能有很多原因。就我而言,它是以下内容:.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=
"data source=(localdb)\v11.0;
initial catalog=Blogging;
integrated security=True;
multipleactiveresultsets=True;""
providerName="System.Data.EntityClient" />
</connectionStrings>
ADO.NET字符串如下所示:
<connectionStrings>
<add name="BlogContext"
providerName="System.Data.SqlClient"
connectionString="Server=.\SQLEXPRESS;Database=Blogging;
Integrated Security=True;"/>
</connectionStrings>
答案 2 :(得分:11)
对我来说,问题是我没有在实体框架的上下文中包含我的数据库集中的实体类。
PS C:\> Get-Process -Id (Get-NetTCPConnection -LocalPort 443).OwningProcess
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName
------- ------ ----- ----- ------ -- -- -----------
143 15 3448 11024 4572 0 VisualSVNServer
答案 3 :(得分:7)
问题可能出在连接字符串中。确保您的连接字符串适用于SqlClient提供程序,没有与EntityFramework相关的元数据内容。
答案 4 :(得分:7)
您可以尝试从模型中删除表格并再次添加。您可以通过从解决方案资源管理器中打开.edmx文件来直观地执行此操作。
步骤:
答案 5 :(得分:3)
当数据库中的现有表格没有适当地映射到代码优先模型时,我已经看到了这个错误。具体来说,我在数据库表中有一个char(1),在C#中有一个char。将模型更改为字符串解决了问题。
答案 6 :(得分:2)
我的问题通过更新连接字符串的元数据部分得到解决。显然,它指向错误的.csdl / .ssdl / .msl参考。
答案 7 :(得分:1)
使用您的连接字符串检查另一件事 - 模型名称。我首先使用了两个实体模型,DB。在配置中,我复制了一个实体连接,重命名了它,并更改了连接字符串部分。我没有改变的是模型名称,所以当实体模型正确生成时,当启动上下文时,EF正在查找实体的错误模型。
看起来很明显,但有四个小时我不会回来。
答案 8 :(得分:1)
对我来说,问题是我使用了connection string
模型(.edmx)生成的ADO.Net
。更改连接字符串解决了我的问题。
答案 9 :(得分:1)
如果您使用的持久化模型缓存由于某种原因或其他原因而过时,也会发生这种情况。如果您的上下文已缓存到文件系统上的EDMX文件中(通过DbConfiguration.SetModelStore),则将不会调用OnModelCreating,因为将使用缓存的版本。因此,如果您的缓存存储中缺少实体,那么即使连接字符串正确,数据库中存在该表且该实体在您的DbContext中已正确设置,您也会收到上述错误。
答案 10 :(得分:0)
如果您首先尝试数据库,请确保您的表格有主键
答案 11 :(得分:0)
添加到配置中的实体(甚至是空实体)的映射将导致实体类型成为上下文的一部分。我们有一个与使用空地图修复的其他实体没有任何关系的实体。
答案 12 :(得分:0)
Visual Studio 2019 似乎为我造成了这种情况。我在2017年通过再次生成edmx模型对其进行了修复。
答案 13 :(得分:0)
消息很清楚,但是我一开始没有得到...
我正在使用同一方法处理两个Entity Framework DB上下文sysContext
和shardContext
。
我已修改\更新的实体来自一个上下文,但是我尝试将其保存到另一个上下文,如下所示:
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();
将实体传递到正确的上下文后,此错误消失了。
答案 14 :(得分:0)
我在Entity Framewrok中遇到了同样的问题,并且通过以下步骤解决了该问题:
1-打开您的Model.edmx 2-更改表位置(用于在cs文件中进行更改) 3保存
希望对您有帮助
答案 15 :(得分:0)
删除.edmx文件,然后再次添加。特别是如果您已升级实体框架。
答案 16 :(得分:0)
我在尝试更新值范围时遇到了EntityFrameworkCore的相同问题。
此方法无效
_dbSet.AttachRange(entity);
_context.Entry(entity).State = EntityState.Modified;
await _context.SaveChangesAsync().ConfigureAwait(false);
添加UpdateRange方法并删除附件和条目后,一切正常
_dbSet.UpdateRange(entity);
await _context.SaveChangesAsync().ConfigureAwait(false);
答案 17 :(得分:0)
对我来说,这是因为我重命名了实体类,当我将其回滚时还可以。
答案 18 :(得分:0)
可能很愚蠢,但是如果您只在某个表上遇到此错误,请不要忘记清理您的项目并重建(可以节省很多时间)
答案 19 :(得分:0)
我有这个
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之前等待,所以我也遇到了同样的错误...
答案 20 :(得分:0)
对我来说,问题是我使用了:
List<Some> someCollection ...;
_dbContext.Remove(someCollection);
代替:
_dbContext.RemoveRange(someCollection);
答案 21 :(得分:0)
确保您已将映射类设置为指向您的 SQL 表
答案 22 :(得分:0)
我遇到了同样的问题,就我而言,我收到此错误消息的原因是我的类文件中的属性标识符与数据库中定义的标识符不匹配,例如我写了一个以大写开头的标识符,而在数据库中它全部是小写。