簡體   English   中英

EntityFramework - 實體代理錯誤

[英]EntityFramework - Entity proxy error

我正在使用 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; }
}

當我嘗試在我的實體上實現 ICloneable 並使用 MemberwiseClone 克隆它時,這也發生在我身上。 當我使用我自己實例化的實體時效果很好。 但是,當我使用它來克隆使用 EF 加載的實體時,每當我嘗試將它添加到 DbSet(或其他各種部分)時,我都會收到此錯誤。

經過一番挖掘,我發現當您克隆一個 EF 加載的實體時,您也在克隆代理類。 代理類攜帶的一件事是對給定實體的包裝器的引用。 由於淺拷貝僅復制對包裝器的引用,因此您會突然擁有兩個具有相同包裝器實例的實體。

在這一點上,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;

    }

上述解決方案可能會出現錯誤“已檢測到關系 y 的角色 x 的沖突更改”。 我使用此方法實現了該錯誤;

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

我希望它也適合你。

我是這樣解決的。

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

         return ctx.Deferrals.AsNoTracking().Where(r => 
         r.DeferralID.Equals(deferralID)).FirstOrDefault();
      }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM