【问题标题】:InsertOrUpdate Generic RepositoryInsertOrUpdate 通用存储库
【发布时间】:2014-05-13 03:46:49
【问题描述】:

请告知,我正在使用带有 UOWgeneric 存储库,并且在测试我的 InsertOrUpdate 方法时出现此错误。(我是 c# 和 EF 的新手)

结果消息:

测试方法UnitTestProject1.ManifestUOW.ManifestUOWTest抛出异常: System.InvalidOperationException:附加类型为“DomainClasses.ManifestDetail”的实体 失败,因为同一类型的另一个实体已经具有相同的主键值。 当使用“附加”方法或将实体的状态设置为“未更改”时,可能会发生这种情况 如果图表中的任何实体具有冲突的键值,则为“已修改”。这可能是因为一些 实体是新的,尚未收到数据库生成的键值。在这种情况下,使用“添加” 方法或“添加”实体状态来跟踪图形,然后将非新实体的状态设置为 “未更改”或“已修改”(视情况而定)。

我的通用存储库

public T FindById(object id)

    {
        return _set.Find(id);
    }

     public void Add(T entity)
    {
        DbEntityEntry entry = this._ctx.Entry(entity);
        if (entry.State != EntityState.Detached)
        {
            entry.State = EntityState.Added;
        }
        else
        {
            this._set.Add(entity);
        }
    }

    public void Update(T entity)
    {
        DbEntityEntry entry = this._ctx.Entry(entity);
        if (entry.State != EntityState.Detached)
        {
            this._set.Attach(entity);
        }
        entry.State = EntityState.Modified;
    }

    public void InsertOrUpdate(T entity, object id)
    {

        var _Record = FindById(id);
        if (_Record != null)
        {

            Update(entity);

        }
        else
        {
            Add(entity);
        }

    } 

我的测试实现

[TestMethod]
    public void ManifestUOWTest()
    {
        ApplicationUOW appUOW = new ApplicationUOW();
        ManifestDetail manD=new ManifestDetail();


        for (var i = 20; i <= 22; i++)
        {

            manD = new ManifestDetail();
            manD.ID = "kkke" + i;
            manD.ManifestID = "kkke";
            manD.ModifiedDate = DateTime.Now;
            manD.PriorityID = 1;
            manD.JobNo = "8888777";
            manD.PartNo = "ppppp";
            manD.OpSeq = "9000";
            manD.QTY = 9;
            manD.Comment = "";
            manD.LitNO = "Lit no";

            appUOW.ManifestDetails.InsertOrUpdate(manD, manD.ID);
        }

        var man = new Manifest();
        man.ID = "kkke";
        man.CreatedDate = DateTime.Now;
        man.ManifestStateID = 2;
        man.MFBldgID = 1;
        man.MFDestBldgID = 2;
        man.UserID = "X6344";

        appUOW.Manifests.InsertOrUpdate(man, man.ID);            
        appUOW.SaveChanges();
 }

我的UOW

namespace DataLayer

{

   public class ApplicationUOW:IDisposable

{

   private AuditorStationDB _context = new AuditorStationDB();

   private IRepository<Manifest> _manifests = null;
   public IRepository<Manifest> Manifests
   {
       get
       {
           if (this._manifests == null)
           {
               this._manifests = new GenericRepository<Manifest>(this._context);
           }
           return this._manifests;
       }
   }


   private IRepository<ManifestDetail> _manifestDetails = null;
   public IRepository<ManifestDetail> ManifestDetails
   {
       get
       {
           if (this._manifestDetails == null)
           {
               this._manifestDetails = new GenericRepository<ManifestDetail>(this._context);
           }
           return this._manifestDetails;
       }
   }



   public void SaveChanges()
   {
       this._context.SaveChanges();
   }

   public void Dispose()
   {
       if (this._context != null)
       {
        this._context.Dispose();
       }
   }

}
}

【问题讨论】:

标签: c# entity-framework


【解决方案1】:

您遇到的问题是您的 InsertOrUpdate() 方法调用了 Update() 方法。

  1. 您首先要求 EF 通过 Id 定位您的实体,所以此时,在 EF 中它正在跟踪该实体。

  2. 然后你将T entity 传递到Update() 中,在其中你的Update() 方法要求它附加() 到EF。 现在 EF 已经在第 1 步跟踪了同一个实体,您正试图要求它 Attach() 同一个实体(两者 实体具有相同的主键)在第 2 步,这就是它失败的原因。

所以要解决你的问题,有两种方法(未测试):

  1. 不要使用 FindById() 来确定 InsertOrUpdate() - 如果 id = 0 可能意味着需要插入 else 更新。

  2. 在调用 Update() 之前,分离您的实体 FindById() - this._ctx.Entry(entity).State = EntityState.Detached

虽然在这篇文章(http://msdn.microsoft.com/en-us/data/jj592676.aspx)中并没有讨论通用存储库,但是在底部可以找到如何在 EF 中实现 InsertOrUpdate 方法的想法。

【讨论】:

  • 我尝试了您的第二种可能的解决方案,但我仍然遇到同样的错误。请注意,我已经使用 update else 在我的 GenericRepository 中插入新行(如果 id==null)。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
  • 2011-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多