

Entity Framework Savechanges İşleminde Objectstatemanager Problemi
-
ben dummy verilerle kayıt yapıp test etmen gerektiğini düşündüm de neyse
stackoverflow da konuyu açarsan oradan bir çözüm bulabilirsin belki
-
çok sık gönderince hata geliyor demişsin. acaba bir queue yapısı oluşturmak mantıklı olur muki?
Mesaj 27 Temmuz 2012 (Cuma) Saat: 11:16'da FCN tarafından düzenlendi. -
cvp gelmiş stackoverflow dan benim dediğim mantıkta..
bir de araştırırken şöyle bir şey gördüm
Set the StoreGeneratedPattern attribute to "Identity" for the primary key column in the Store part of the model.
bazılarının hatası bundan kaynaklı. identity ya da store olarak ayarlayıp dene istersen
Mesaj 26 Temmuz 2012 (Persembe) Saat: 17:27'da unbalanced tarafından düzenlendi. -
unbalanced bunu yazdı:
-----------------------------cvp gelmiş stackoverflow dan benim dediğim mantıkta..
bir de araştırırken şöyle bir şey gördüm
Set the StoreGeneratedPattern attribute to "Identity" for the primary key column in the Store part of the model.
bazılarının hatası bundan kaynaklı. identity ya da store olarak ayarlayıp dene istersen
Mesaj 26 Temmuz 2012 (Persembe) Saat: 17:27'da unbalanced tarafından düzenlendi.
-----------------------------doğru dediğin gibi olabilir şöyle birşey farkettim
1 veri ekledim diyelim
sonra 1 tane daha eklediğimde ilk eklediğimi tekrar ekliyor
3. ekleyişimde de ilk ikisini tekrar ekliyor.
edit: primary keylerin StoreGeneratedPattern propunu Identity yaptım yine değişen bişey yok :(
edit:ne sikim iş
Mesaj 27 Temmuz 2012 (Cuma) Saat: 10:47'da tqrL tarafından düzenlendi.
Mesaj 27 Temmuz 2012 (Cuma) Saat: 10:57'da tqrL tarafından düzenlendi. -
ObjectSet.AddObject(entity);
objectSet dediğin nedir? sen eğer her insert de yeni bir instance yaratmıyorsan. sürekli objectset in içine ekliyor ve sen savechanges dediğinde oluyor.
mantık basit niye karıştırdın?
Datamodel datamodel = new Datamodel();
datamodel.kitaplar.add(hede);
datamodel.savaChanges();
gibi.. tam kodları yazarsan yardımcı olalım
-
//BaseService.cs
public class BaseService<T> :IDisposable where T : class { ObjectContext _context; IObjectSet<T> _objectSet; // Data nesnelerimiz üzerinde değişiklikler yapmamızı sağlar (AddObject,Attach,DeleteObject,Detach) //İki kurucu fonksiyonumuz, birinci ile daha önceden belirlediğimiz bir tipte entitycontextimizi belirliyoruz, ikincisinde ise istediğimiz contexti sınıfımızın objectseti olarak set ediyoruz. public BaseService() { _context = new ustadanEntities(); // entitymizi kullanabilmek için gerekli namespace'i using ile refere etmeyi unutmayın. _objectSet = _context.CreateObjectSet<T>(); //Parametre olarak geçtiğimiz contexti sınıfımızın ObjectSet'i olarak belirliyoruz } public BaseService(ObjectContext objectContext) { _context = objectContext; _objectSet = _context.CreateObjectSet<T>(); //Parametre olarak geçtiğimiz contexti sınıfımızın ObjectSet'i olarak belirliyoruz } //Entity'imizi otomatik tip dönüşümü ile Queryable yapıyoruz public IQueryable<T> AsQueryable() { return _objectSet; } //parametre olarak geçtiğimiz lambda koşuluyla uyuşan ilk sonucu alan sorgu public T First(Expression<Func<T, bool>> where) { return _objectSet.FirstOrDefault(where); } //parametre olarak geçtiğimiz lambda koşuluyla uyuşan sonuçları alan sorgu public IEnumerable<T> Find(Expression<Func<T, bool>> where) { return _objectSet.Where(where); } public bool Any(Expression<Func<T, bool>> where) { return _objectSet.Any(where); } //ekleme,silme ve güncelleme işlemleri public void Delete(T entity) { _objectSet.DeleteObject(entity); SaveChanges(); } public void Add(T entity) { _objectSet.AddObject(entity); SaveChanges(); //Context.ObjectStateManager.GetObjectStateEntry(entity).AcceptChanges(); } public void Attach(T entity) { _objectSet.Attach(entity); SaveChanges(); } public void Update(Expression<Func<T, bool>> where, T entity) { var ent = First(where); ent = entity; SaveChanges(); } public void SaveChanges() { try { _context.SaveChanges(); } catch (Exception ex) { // Get All properties from the Exception var properties = ex.GetType().GetProperties(); foreach (PropertyInfo p in properties) { //Search Properties of Exception for StateEntries if (p.Name == "StateEntries") { //Get the entities var entities = (IEnumerable)p.GetValue(ex, null); foreach (ObjectStateEntry objectStateEntry in entities) { //Accept Changes (ie Abandon save of Entity Causing issues) objectStateEntry.AcceptChanges(); } } } //Throw the Exception so the upper level know it have a problem. throw; } } //Son fonksiyonumuz diğerlerine nezaran daha spesifik olduğu için sona bıraktım, sorugumuza parametre olarak hem where ifadesi hem de orderby ifadesi geçiyoruz public IEnumerable<T> GetAllByDescending<F>(Expression<Func<T, bool>> query, Expression<Func<T, F>> order, int skip = 0, int take = 0) { // _context.Refresh(RefreshMode.StoreWins, _objectSet); IQueryable<T> tq = _objectSet.AsQueryable(); if (query != null) tq = _objectSet.Where(query); tq = tq.OrderByDescending(order); if (take != 0) { tq = tq.Skip(skip).Take(take); } return tq; } public IEnumerable<T> SelectAll(Expression<Func<T, bool>> query = null) { IQueryable<T> tq = _objectSet.AsQueryable(); if (query != null) tq = _objectSet.Where(query); return tq; } #region Implementation of IDisposable public void Dispose() { if(_context!=null) { _context.Dispose(); } GC.SuppressFinalize(this); } #endregion } }//AuthService.cs -> her tablo için böyle servisler var ben en kısasını yazdım
public class AuthService : BaseService<TBL_AUTH> { private static readonly AuthService _instance = new AuthService(); public static AuthService Instance { get { return _instance; } } public TBL_AUTH First(int id) { return base.First(p => p.AUTH_ID == id); } public void Update(decimal id, TBL_AUTH entity) { base.Update(p => p.AUTH_ID == id, entity); } } -
public void Add(T entity) {_objectSet = new ObjectSet(); //Burası _objectSet.AddObject(entity); SaveChanges(); //Context.ObjectStateManager.GetObjectStateEntry(entity).AcceptChanges(); }bi dene bakalım bişeyler olacak gibi
Mesaj 27 Temmuz 2012 (Cuma) Saat: 13:49'da SinusX tarafından düzenlendi. -
sanırım problem şurada;
oracle auto increment olayını yaparken sequence + trigger kullanması gerekiyor
tabi entityi ekletirken primery keyi set etmeden verdiğimiz için 0 değeriyle gidiyor
dbye işliyor çünkü db tarafında trigger sequenceden aldığı değeri set edip insert ediyor fakat servis katmanında patlıyor.
-
hata zaten veritabanına kayıt ederken değil, ObjectStateManager da aynı key olduğu için veriyor. Arkadaşlarn dediği gibi yeni bir nesne create ederek deneyebilirsin. Benim daha önceden kastım böyle bir şeydi aslında, farklı bilgi içerikli nesneleri eklemek. bir for döngüsü yerine ekleme metodunu ard arda farklı nesneleri parametre olarak geçirip, çağırma..
Ayrıca breakpoint koyarak, eklediğin nesnelerin id sine bakıp ve eklenecek olan nesnenin idsine bakıp sorunu görebilirsin. (bir metod yazarak modele eklenen bilgileri listele ve eklenecek olan verinin keyi ile karşılaştır)
-
SinusX bunu yazdı:
-----------------------------public void Add(T entity) {_objectSet = new ObjectSet(); //Burası _objectSet.AddObject(entity); SaveChanges(); //Context.ObjectStateManager.GetObjectStateEntry(entity).AcceptChanges(); }bi dene bakalım bişeyler olacak gibi
Mesaj 27 Temmuz 2012 (Cuma) Saat: 13:49'da SinusX tarafından düzenlendi.
-----------------------------public void Add(T entity)
{
_context = new ustadanEntities();
_objectSet = _context.CreateObjectSet<T>();
_objectSet.AddObject(entity);
SaveChanges();
//Context.ObjectStateManager.GetObjectStateEntry(entity).AcceptChanges();
}
şu şekilde yaptım oldu galiba.