2012-09-07 13 views
16

私はEntityframeworkを使用しているシステムで作業していますが、現在12montsを超えており、昨日までプロジェクトは順調に進んでいます。それが起こる。 は私が前にやっていることへの異なる何もしないが、私は問題のエンティティをロードし、私は次のエラーを取得する任意の子エンティティにアクセスしようと一度午前:EntityFramework - エンティティプロキシエラー

The entity wrapper stored in the proxy does not reference the same proxy 

誰もが実際に何をこの上の任意の光を当てることができますどういう意味ですか?

私のコードを表示することは本当に助けになりません。

は、ここでは、コードの簡易版である:正しくDeparturePointとDestinationPointが、見積もり負荷をアクセスするとき

var quote = new QuoteHelper().GetById(orderId); 
var updatedQuotes = new Provider().GetExportQuotes(quote.DeparturePoint.Id,quote.DestinationPoint); 

エラーが発生し、すべてのプロパティが読み込まれます。

エンティティの引用は少しのようになります。私は私のエンティティでICloneableを実装しようとしたとMemberwiseCloneを使用してクローン化されたとき

public class Quote : BaseQuote, ICloneable 
{ 
    public Guid DeparturePointId { get; set; } 
    public virtual LocationPoint DeparturePoint{ get; set; } 

    public Guid DestinationPointId { get; set; } 
    public virtual LocationPoint DestinationPoint{ get; set; } 
} 

答えて

32

は、これはあまりにも私に起こりました。私が自分自身をインスタンス化したエンティティを使用していたときにうまくいった。しかし、これを使ってEFを使用して読み込まれたエンティティをクローンすると、DbSet(または他のさまざまな部分)に追加しようとするたびにこのエラーが発生しました。

掘り下げた後、EFをロードしたエンティティをクローンすると、プロキシクラスもクローニングされていることがわかりました。プロキシクラスが持ち歩くことの1つは、指定されたエンティティのラッパーへの参照です。浅いコピーはラッパーへの参照のみをコピーするので、同じラッパーインスタンスを持つ2つのエンティティが突然存在します。

この時点で、EFはいたずらを目的としたエンティティに対して異なるプロキシクラスを作成または借用したと判断し、それをブロックします。

編集

ここに私はこの問題を回避するために作成された抜粋です。これは、EFのプロパティだけをコピーするという面倒な作業を行いますが、完璧ではありません。コピーする必要があるプライベートフィールドがある場合は、それを変更する必要があることに注意してください。溶液上の

/// <summary> 
    /// Makes a shallow copy of an entity object. This works much like a MemberwiseClone 
    /// but directly instantiates a new object and copies only properties that work with 
    /// EF and don't have the NotMappedAttribute. 
    /// </summary> 
    /// <typeparam name="TEntity">The entity type.</typeparam> 
    /// <param name="source">The source entity.</param> 
    public static TEntity ShallowCopyEntity<TEntity>(TEntity source) where TEntity : class, new() 
    { 

     // Get properties from EF that are read/write and not marked witht he NotMappedAttribute 
     var sourceProperties = typeof(TEntity) 
           .GetProperties() 
           .Where(p => p.CanRead && p.CanWrite && 
              p.GetCustomAttributes(typeof(System.ComponentModel.DataAnnotations.NotMappedAttribute), true).Length == 0); 
     var newObj = new TEntity(); 

     foreach (var property in sourceProperties) 
     { 

      // Copy value 
      property.SetValue(newObj, property.GetValue(source, null), null); 

     } 

     return newObj; 

    } 
+1

ありがとう、私は恐ろしいクローンメソッドを持っていて、私は必要とされた魔法のように見えるmemberwiseはそうではないようです。ありがとう。 – JamesStuddart

+0

MemberwiseCloneはしばしばあなたが必要とする魔法ですが、EFはいくつかのユニークなことを行います。ちなみに、この解決策では不十分だとわかった場合、私は安いクローニングの仕組みのために[AutoMapper](http://automapper.org/)を使っている人についても聞いたことがあります。これを意図したものではありませんが、それが完全に良い解決策ではありません。 –

+0

ありがとうございます、私は問題のためにボットの仕事をしましたが、私はそれに戻ってくる時間を得るとき、あなたが与えたソリューションの1つを実装します。あなたの洞察をお寄せいただきありがとうございます。この問題についてはそこにはあまり出ていないようですが、これが他の人にも役立つことを願っています。 NotMappedAttributeプロパティを使用する場合は – JamesStuddart

1

ような「関係Yの役割xに競合する変更がが検出された」エラーとして生じ得ます。私はこの方法でこのエラーを解決します。

public virtual TEntity DetachEntity(TEntity entityToDetach) 
    { 
     if (entityToDetach != null) 
      context.Entry(entityToDetach).State = EntityState.Detached; 
     context.SaveChanges(); 
     return entityToDetach; 
    } 

私はそれもあなたのために働くことを願っています。