2017-07-24 97 views
6

Genellikle değişmeyen bazı varlıkları önbelleğe almak için Entity Framework 6 ve ObjectCache kullanıyorum. Ancak, farklı bir bağlamdan alındıkları için önbelleğe alınan varlıkları kaydetmeye çalışırken bir hatayla karşılaştım. kaydetmeden önce, doğrulanmış ve nesnenin durumu müstakil ama ben bunu kadar bu hata kurtulmak olamazdı:Entity Framework 6 ve ObjectCache: kaydetme sorunları

public void Save(Product obj) 
{ 
    var objInDb = dbContext.Products.Find(obj.Id); 

    if (objInDb == null) 
    { 
     dbContext.Products.Add(obj); 
     dbContext.SaveChanges(); 
    } 
    else 
    { 
     dbContext.Entry(objInDb).CurrentValues.SetValues(obj); 
     dbContext.Entry(objInDb).State = EntityState.Modified; 
     dbContext.SaveChanges(); 
    } 
} 
açıklanan çözümü sonrasında sabit hayata geçirildi

Orjinal hatası: bir varlık ekleme 'C' türü aynı türde başka bir varlık zaten aynı birincil anahtar değerine sahip olduğundan başarısız oldu. Bu, 'Attach' yöntemini kullanırken veya bir varlığın durumunu 'Değişmeyen' veya 'Değiştirildi' durumuna ayarlandığında, grafikteki herhangi bir varlığın çakışan anahtar değerlere sahip olması durumunda gerçekleşebilir. Bunun nedeni, bazı varlıkların yenidir ve henüz veritabanı tarafından oluşturulan anahtar değerleri almadı. Bu durumda, grafiği izlemek için 'Ekle' yöntemini veya 'Eklenen' varlık durumunu kullanın ve ardından yeni olmayan varlıkların durumunu 'Değiştirilmedi' veya 'Değiştirildi' durumuna ayarlayın.

orijinal kod oldu:

if (obj.Id == 0) 
{ 
    context.Products.Add(obj); 
} 
else 
{ 
    context.Entry(obj).State = EntityState.Modified; 
} 

context.SaveChanges(); 

bu işlemek için daha iyi bir yolu var mı? Önbelleğimi atlamayı ve nesneyi almak için DB'ye vurmayı gerçekten sevmiyorum çünkü bana gereksiz geliyor.

+0

O zaman çalışmayan orijinal kod neydi? – DavidG

+0

Sadece orijinal kodu soruma ekledim. –

+0

Bağlamınızda "Configuration.ProxyCreationEnabled" etkin var mı? Tahminim, proxy'yi gerçek varlık türü yerine önbelleğinizde depolamanızdır. – DavidG

cevap

0

Sanırım "vurma" debb'nin tek yolu, aşağıdaki gibi olacaktır. İlk özel durumunuza göre, bu varlık için db'yi zaten başka bir yere "vurduğunuzu" unutmayın.

if (obj.Id == 0) 
{ 
    context.Products.Add(obj); 
} 
else 
{ 
    var localProduct = context.Products.Local.FirstOrDefault(x => x.Id == obj.Id); 
    if (localProduct == null) 
    { 
     context.Entry(obj).State = EntityState.Modified; 
    } 
    else 
    { 
     context.Entry(localProduct).CurrentValues.SetValues(obj); 
    } 
} 
context.SaveChanges();