2012-11-08 16 views
5

Genel bir depo uygulamasına sahibim. Asp.net mvc C# kullanıyorum, kod ilk varlık çerçevesi. aşağıdaki gibi benim taban depo Sil ve GetById uygulananYumuşak Silme Özellikli Genel Depo Özelliği

public interface ISoftDelete 
{ 
    bool IsDeleted { get; set; } 
} 

:

public virtual void Delete(T entity) 
    { 
     if (entity is ISoftDelete) 
     { 
      ((ISoftDelete)entity).IsDeleted = true; 
     } 
     else 
     { 
      dbset.Remove(entity); 
     } 
    } 

    public virtual T GetById(long id) 
    { 
     T obj = dbset.Find(id); 
     if (obj is ISoftDelete) 
     { 
      if (((ISoftDelete)obj).IsDeleted) 
       return null; 
      else 
       return obj; 
     } 
     else 
     { 
      return obj; 
     } 
    } 

Şimdi, 2 soru var

Ben ISoftDelete adında bir arayüz oluşturdu.

1) Bu yaklaşım iyi bir yaklaşım mıdır? Performansla ilgili sorunlar var mı?

2) taban depoda Benim asıl getAll fonksiyonu şu şekildedir:

public virtual IEnumerable<T> GetAll() 
    { 
      return dbset.ToList(); 
    } 

nasıl kayıtları listelemek için bunu değiştirmek hallerde isDeleted == false, T ISoftDelete türetilmiştir zaman?

Teşekkür ederiz!

cevap

4

1): getAll için bu kodu deneyebilirsiniz. Eğer başka bir yerde kontrol etmeyeceğinizden eminseniz tamam olabilir. Performans açısından, IsDeleted == true numaralı kayıtları kaldıramazsanız ve bunları asla db'den almazsanız daha iyi olur. Bu yöntemleri geçersiz kılan ve ISoftDelete nesnesi için yeni mantıkları uygulayan yeni bir taban deposu türetmeniz gerekebilir.

public abstract class BaseRepository<T> 
{ 
    // protected dbset; 

    public virtual void Delete(T entity) 
    { 
     dbset.Remove(entity); 
    } 

    public virtual T GetById(long id) 
    { 
     return dbset.Find(id); 
    } 

    public virtual IEnumerable<T> GetAll() 
    { 
     return dbset.ToList(); 
    } 
} 

public abstract class SoftDeleteRepository<T> : BaseRepository<T> where T : ISoftDelete 
{ 
    public override void Delete(T entity) 
    { 
     entity.IsDeleted = true; 
    } 

    public override T GetById(long id) 
    { 
     return (from t in dbSet 
       where !t.IsDeleted && t.Id == id select t) 
       .FirstOrDefault(); 
    } 

    public override IEnumerable<T> GetAll() 
    { 
     return (from t in dbset where !t.IsDeleted select t).ToList(); 
    } 
} 

public static class RepositoryFactory 
{ 
    public static BaseRepository<T> GetInstance<T>() 
    { 
      // pseudo code 
      if (typeof(T) implements ISoftDelete) 
       return repository of T which extends SoftDeleteRepository 
      return repository of T which extends BaseRepository 
    } 
} 

2)

return (from t in dbset where 
     (t is ISoftDelete && !(t as ISoftDelete).IsDeleted) || 
     !(t is ISoftDelete)) 
.ToList(); 
+0

+1 güzel çözüm –

+0

kamu kılma T GetById (uzun id) bu fonksiyon t.Id. bir hata atar gibi bir şey olabilir – SherleyDev

+0

BaseRepository öğesinde bir "GetById (long id)" yöntemini kullanırsanız, bu, projenizdeki herhangi bir varlık örneğinin bir "long Id" özelliğine sahip olduğunu varsaydığınızı gösterir. Bu gereksinimi karşılamak için 'IEntity {long Id {get; }} ve tüm varlıklara uygulayın. Ve bu arayüzden 'ISoftDelete' türetin. arabirim ISoftDelete: IEntity {bool IsDeleted {get; set; }}. Ve şimdi SoftDeleteRepository, her T örneğinin Id ve IsDeleted özelliklerine sahip olduğundan emin. –

0

Yaklaşımınız bana iyi görünüyor. Bence, tamamıyla test edilmiş bir testin başarısız olduğunu düşünüyorum. Bu bunu bilmek gerekir her zaman if (entity is ISoftDelete) kontrolü için ok görünmüyor

public virtual IEnumerable<T> GetAll() 
    { 
     var queryable = dbset; 
     if (typeof(ISoftDelete).IsAssignableFrom(typeof(T))) 
     { 
      queryable = queryable.Where(q => q.IsDeleted == false); 
     } 

     return queryable.ToList(); 
    } 
İlgili konular