22

私はEntityframeworkを使用するシステムに取り組んでおり、現在12か月以上にわたってプロジェクトを進めています。昨日までプロジェクトは順調に進んでおり、なぜ発生するのかわからない奇妙なエラーが発生しました。以前に行ったことと何も変わりませんが、問題のエンティティをロードして子エンティティにアクセスしようとすると、次のエラーが発生します。

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

誰かがこれが実際に何を意味し、何がこれを引き起こすのかについて何か光を当てることができますか?

私のコードを表示しても、実際には役に立ちません。

コードの簡略化されたバージョンは次のとおりです。

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

DeparturePointとDestinationPointにアクセスするとエラーが発生しますが、Quoteが正しく読み込まれ、すべてのプロパティが読み込まれます。

エンティティQuoteは次のようになります。

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; }
}
4

3 に答える 3

45

これは、エンティティにICloneableを実装し、MemberwiseCloneを使用してクローンを作成しようとしたときにも発生しました。自分でインスタンス化したエンティティを使用していたときに、うまく機能しました。ただし、これを使用して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;

    }
于 2012-09-11T16:19:48.363 に答える
1

上記の解決策は、「関係yの役割xへの競合する変更が検出されました」などのエラーが発生する可能性があります。私はこの方法を使用してそのエラーを達成します。

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

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

于 2014-02-02T22:01:42.203 に答える
1

私はそれをこのように解決しました。

using (var ctx = new MyContext())
      {
         ctx.Configuration.ProxyCreationEnabled = false;

         return ctx.Deferrals.AsNoTracking().Where(r => 
         r.DeferralID.Equals(deferralID)).FirstOrDefault();
      }
于 2019-01-09T22:33:18.860 に答える