Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用实体框架初始化数据_C#_Entity Framework - Fatal编程技术网

C# 使用实体框架初始化数据

C# 使用实体框架初始化数据,c#,entity-framework,C#,Entity Framework,我想在应用程序运行之前初始化数据库中的虚拟数据。我有一个SQL脚本,可以将数据直接插入到表中 问题是,当我要更新元素时,会出现以下异常: EntityFramework.dll中的“System.InvalidOperationException”en EntityFramework.dll:附加类型为“Es.Udc.DotNet.MiniPortal.Model.Book”的实体失败,因为相同类型的另一个实体已具有相同的主键值。如果图形中的任何实体具有冲突的键值,则在使用“Attach”方法或

我想在应用程序运行之前初始化数据库中的虚拟数据。我有一个SQL脚本,可以将数据直接插入到表中

问题是,当我要更新元素时,会出现以下异常:

EntityFramework.dll中的“System.InvalidOperationException”en EntityFramework.dll:附加类型为“Es.Udc.DotNet.MiniPortal.Model.Book”的实体失败,因为相同类型的另一个实体已具有相同的主键值。如果图形中的任何实体具有冲突的键值,则在使用“Attach”方法或将实体状态设置为“Unchanged”或“Modified”时可能会发生这种情况。这可能是因为某些实体是新的,尚未收到数据库生成的键值。在这种情况下,使用“添加”方法或“添加”实体状态跟踪图形,然后根据需要将非新实体的状态设置为“未更改”或“已修改”。

这是我的更新方法:

public void Update(E entity)
{
    dbContext.Entry<E>(entity).State = EntityState.Modified;
    dbContext.SaveChanges();
}
公共作废更新(E实体)
{
dbContext.Entry(entity.State=EntityState.Modified;
dbContext.SaveChanges();
}

我认为这是因为EF不跟踪项目,但我不知道我能做什么。初始化虚拟数据并由EF跟踪的最佳方法是什么?谢谢。

我建议您在将实体发送到更新方法之前进行选择(使用EF),然后在将实体设置为修改后尝试将其附加到上下文(这取决于您是否使用changetraking选项)

dbContext.Set().Attach(实体);
例如,这是我的存储库更新方法(仅举一个例子):

public void更新(TEntity更新,Tkey)
{
updated.ObjectState=ObjectState.Modified;
var existing=_dbSet.Find(键);
if(existing==null)返回;
existing.ObjectState=ObjectState.Modified;
dbContext.Entry(现有).CurrentValues.SetValues(更新);
dbContext.Set().Attach(现有);
}
我认为这是因为EF不跟踪项目

这是因为EF正在跟踪实体。使用相同的DbContext实例,您试图通过实体的不同实例读取和更新实体。实体通过引用进行跟踪

这意味着传递给此
Update()
方法的实体与从数据库中读取的实体不同

如果您没有在代码中明确执行此操作,则可能是代码经过映射阶段,其中要更新的实体是新的(明确地或通过反射),并从另一个实体填充,例如通过AutoMapper映射的viewmodel

另一种情况是上下文的生存期太长,例如,因为它是从静态变量和/或单例或配置不正确的依赖项注入容器中使用的

因此,要么:

  • 修复DbContext的生存期,以便在上下文的不同实例上进行查找和更新
  • 如果必须在与更新相同的DbContext实例上进行查找,请确保更新从第一次查找返回的实体
  • 在查找时。多次查询同一实体可能有意义,在这种情况下,在某些位置使用非跟踪实体可能是解决方案

无论您选择哪种方法,都需要处理并发性,这是您不想自己处理的

尝试使用EF选择一个“可能在之前”选项。。类似于var query=db。Book.ToList()你能在尝试修改数据时发布一些代码(C#)吗?嗨@federicoscamuzzi我用代码编辑了答案,但我无法编辑,因为这是老师给的库
 dbContext.Set<TEntity>().Attach(entity);
public void Update(TEntity updated, Tkey key)
        {
            updated.ObjectState = ObjectState.Modified;

            var existing = _dbSet.Find(key);
            if (existing == null) return;

            existing.ObjectState = ObjectState.Modified;
            dbContext.Entry(existing).CurrentValues.SetValues(updated);
            dbContext.Set<TEntity>().Attach(existing);



        }