2014-12-15 22 views
5

MVC Uygulamamda daha sonra kullanmak üzere bir Genel Depo ile bir kitaplık oluşturmaya çalışıyorum. ...Genel Deposu özel yöntem ekle

public class Documento : AuditableEntity<int> 
{ 
    public string Descripcion { get; set; }   
    public string Foto { get; set; } 

    public virtual Usuario Usuario { get; set; } 
} 

public class Gasto : AuditableEntity<int> 
{ 
    public int? TaxiId { get; set; }   
    public int TipoGastoId { get; set; } 
    public DateTime Fecha { get; set; } 
    public double Importe { get; set; } 
    public int Kilometros { get; set; } 
    public string Descripcion { get; set; } 
    public string Foto { get; set; } 

    public virtual Usuario Usuario { get; set; } 
    public virtual Taxi Taxi { get; set; } 
    public virtual TipoGasto TipoGasto { get; set; } 
    public virtual PartidaTarjetas PartidaTarjetas { get; set; } 

    public virtual ICollection<Tarea> Tareas { get; set; }  

    public int? PartidaTarjetasId { get; set; } 

    public Gasto() 
    { 
     Tareas = new List<Tarea>(); 
    } 
} 

public class Nivel : Entity<int> 
{ 
    public string Descripcion { get; set; } 
    public string PaginaInicio { get; set; } 

    public virtual ICollection<Usuario> Usuarios { get; set; } 

    public Nivel() 
    { 
     Usuarios = new List<Usuario>(); 
    } 
} 

Benim sorunum bu yöntemi uygulamıyor olmasıdır ... kod ...

public abstract class BaseEntity 
{ 
} 

public interface IEntity<T> 
{ 
    T Id { get; set; } 
} 

public abstract class Entity<T> : BaseEntity, IEntity<T> 
{ 
    public virtual T Id { get; set; } 
} 

public interface IAuditableEntity 
{ 
    int? UsuarioId { get; set; } 
    DateTime CreatedDate { get; set; } 
    string CreatedBy { get; set; } 
    DateTime UpdatedDate { get; set; } 
    string UpdatedBy { get; set; } 
} 

public abstract class AuditableEntity<T> : Entity<T>, IAuditableEntity 
{ 
    public int? UsuarioId { get; set; } 
    public DateTime CreatedDate { get; set; } 
    public string CreatedBy { get; set; } 
    public DateTime UpdatedDate { get; set; } 
    public string UpdatedBy { get; set; } 
} 

public interface IGenericRepository<T> where T : BaseEntity 
{ 
    IEnumerable<T> GetAll(); 
    IEnumerable<T> GetByUsuarioId(int usuarioId); 
    T GetById(int id); 
    T Add(T entity); 
    T Delete(T entity); 
    void Edit(T entity); 
    void Save(); 
} 

public class GenericRepository<T> : IGenericRepository<T> 
    where T : BaseEntity 
{ 
    protected DbContext _entities; 
    protected readonly IDbSet<T> _dbset; 

    public GenericRepository(DbContext context) 
    { 
     _entities = context; 
     _dbset = context.Set<T>(); 
    } 

    public virtual IEnumerable<T> GetAll() 
    { 
     return _dbset.AsEnumerable<T>(); 
    } 

    public IEnumerable<T> FindBy(Expression<Func<T, bool>> predicate) 
    { 
     IEnumerable<T> query = _dbset.Where(predicate).AsEnumerable(); 
     return query; 
    } 


    public virtual IEnumerable<T> GetByUsuarioId(int usuarioId) 
    { 
     // NO SÉ COMO IMPLEMENTAR ESTE METODO!!!!! 
     return null; 
     // NO SÉ COMO IMPLEMENTAR ESTE METODO!!!!! 
    } 

    public virtual T GetById(int id) 
    { 
     return _dbset.Find(id); 
    } 

    public virtual T Add(T entity) 
    { 
     return _dbset.Add(entity); 
    } 

    public virtual T Delete(T entity) 
    { 
     return _dbset.Remove(entity); 
    } 

    public virtual void Edit(T entity) 
    { 
     _entities.Entry(entity).State = EntityState.Modified; 
    } 

    public virtual void Save() 
    { 
     _entities.SaveChanges(); 
    } 
} 

aşağıdaki gibidir Ve bunlar benim sınıfların POCO bazılarıdır

public virtual IEnumerable<T> GetByUsuarioId(int usuarioId) 
    { 
     // NO SÉ COMO IMPLEMENTAR ESTE METODO!!!!! 
     return null; 
     // NO SÉ COMO IMPLEMENTAR ESTE METODO!!!!! 
    } 

Sadece IAuditable tip ... olduğunda sonuçlar döndürmesi gereken genel bir yöntemdir, aynı zamanda bir şey olmalı ...

public virtual IEnumerable<T> GetByUsuarioId(int usuarioId) 
    { 
     return _dbset.FindBy(c => c.UsuarioId == usuarioId); 
    } 

Yardım edebilir misiniz ?, Teşekkürler.

Merhaba C Bauer ... Sonra

public interface IGenericRepository<T> where T : BaseEntity 

şimdi
public abstract class BaseEntity 
{ 
} 

public interface IEntity<T> 
{ 
    T Id { get; set; } 
} 

public abstract class Entity<T> : BaseEntity, IEntity<T> 
{ 
    public virtual T Id { get; set; } 
} 

public interface IAuditableEntity 
{ 
    int? UsuarioId { get; set; } 
    DateTime CreatedDate { get; set; } 
    string CreatedBy { get; set; } 
    DateTime UpdatedDate { get; set; } 
    string UpdatedBy { get; set; } 
} 

public abstract class AuditableEntity<T> : Entity<T>, IAuditableEntity 
{ 
    public int? UsuarioId { get; set; } 
    public DateTime CreatedDate { get; set; } 
    public string CreatedBy { get; set; } 
    public DateTime UpdatedDate { get; set; } 
    public string UpdatedBy { get; set; } 
} 

Ve GenericRepositry olduğunu ...

Not .. ¿?

public interface IGenericRepository<T> where T : ¿¿ ?? 
+0

Sadece "T" jenerik parametresinin "IAuditable" değerini uyguladığından emin olmaya çalışıyor musunuz? Genel kısıtlamaların amacı budur: http://msdn.microsoft.com/en-us/library/d5x73970.aspx. –

+0

Örneğin Documento.cs, AuditableEntity uygular. –

+0

@ JesúsSánchez Merhaba İsa, diğer kullanıcıları yanıtlarınıza eklemekten kaçınmalısınız. Bunun yerine, kodlarında sahip olduğunuz sorunu ele alan bir yanıt ekleyin. –

cevap

0

Bu her zaman doğru olan bir şeyse, kod tabanınız boyunca zorlanacak temel sanal yönteminize ekleyin.

public virtual IEnumerable<T> GetByUsuarioId(int usuarioId) 
{ 
    if (!typeof(T).GetInterfaces().Contains(typeof(IAuditable)) 
     return Enumerable.Empty<T>(); // per OffHeGoes' suggestion 

    return _dbset.FindBy(c => c.UsuarioId == usuarioId); 
} 

performans kaygıları ve bu çözüm ile potansiyel mantık gizleme kaygıları hem vardır, aşağıdaki yorum başına, Verilen (ve hepinize teşekkür). Sorunu çözmenin en zarif yolu bu değil, ama gerçekten çözüyor. sadece IRepository<IAuditable> çalışır, böylece

+0

Geri dönen null bir yanlış ad olduğu için bir NotImplementedException veya bir şey atacağım. –

+0

@CBauer Tamamen katılıyorum. Bu, OP'nin kodunun nihayetinde geri döndüğünü ve neyi geri almak istediğiyle ilgili niyetini yorumlamamayı tercih ettiğimi söyledi. –

+0

C Bauer, Orijinal sorumu düzenledim, lütfen kontrol edin ... Teşekkürler –

2

Türlenmiş depo uzatma sınıfını uygulayabilirsiniz:

public static class Extensions 
    { 
     public static IEnumerable<IAuditable> GetUsuarioById(this IRepository<IAuditable> repository, int id) 
     { 
      return repository.FindBy(audible => audible.Id == id); 
     } 
    } 

Düzenleme:

using System; 
using System.Collections.Generic; 
using System.Linq.Expressions; 

namespace StackOverflowPlayground 
{ 
    class JesusPlayground 
    { 
     public JesusPlayground() 
     { 
      var auditableRepo = new AuditableRepo(); 
      auditableRepo.GetUsuarioById(1); 

      var otherRepo = new OtherRepo(); 
      //otherRepo. (does not have GetUsuarioById 


      var auditableRepoNotUsingTheActualClass = new GenericRepository<IAuditable>(); 
      auditableRepoNotUsingTheActualClass.GetUsuarioById(1); //still works! 
     } 
    } 


    public static class Extensions 
    { 
     public static IEnumerable<IAuditable> GetUsuarioById(this IRepository<IAuditable> repository, int id) 
     { 
      return repository.FindBy(audible => audible.Id == id); 
     } 
    } 



    public class OtherRepo : IRepository<OtherType> 
    { 
     public IEnumerable<OtherType> FindBy(Expression<Func<OtherType, bool>> expr) 
     { 
      throw new NotImplementedException(); 
     } 
    } 

    public class OtherType 
    { 
    } 

    public interface IAuditable 
    { 
     int Id { get; set; } 
    } 

    public interface IRepository<T> 
    { 
     IEnumerable<T> FindBy(Expression<Func<T, bool>> expr); 
    } 

    public class GenericRepository<T> : IRepository<T> 
    { 
     public IEnumerable<T> FindBy(Expression<Func<T, bool>> expr) 
     { 
      throw new NotImplementedException(); 
     } 
    } 
    class AuditableRepo : IRepository<IAuditable> 
    { 
     public IEnumerable<IAuditable> FindBy(Expression<Func<IAuditable, bool>> expr) 
     { 
      throw new NotImplementedException(); 
     } 
    } 
} 
+0

İki depo kullanmalı mıyım? ... GenericRepository ve AuditableRepo ?? –

+0

Bu, uygulamanızın nasıl oluşturulduğuna bağlı. Veri erişiminin oluşturulma şeklini standartlaştırmak için her zaman deposu kullandım. Bunu kolayca yapabilirsiniz: 'var auditableRepoNotUsingTheActualClass = new GenericRepository (); '' auditableRepoNotUsingTheActualClass.GetUsuarioById (1); // hala çalışır! ' –

+0

@ JesúsSánchez Orijinal kodunuzu kullanmaya devam edebilirsiniz, gönderdiğim örnek sadece küçük bir kod örneği ve nasıl çalıştığı. –

0

sen bu depoları kullanılarak planlıyoruz nasıl emin değil senin kod (bu nedenle bunları nasıl tüketeceğinizle ilgili olmayabilir), ancak neden başka bir miras katmanı eklemiyorsunuz?

public class AuditableRepository<T> : GenericRepository<T> 
    where T: IAuditableEntity, BaseEntity 

hangisinde ilgili mantığını uygulamak:

public virtual IEnumerable<T> GetByUsuarioId(int usuarioId) 
{ 
    //TODO: default behaviour 
} 

Sonra Denetlenebilir türleri için bir depo oluşturmak: En GenericRepository olarak

public override IEnumerable<T> GetByUsuarioId(int usuarioId) 
{ 
    //TODO: auditable behaviour 
} 

Açıkçası bu anlama geliyor Kod aldığınızın farklı depoları bilmesi gerekiyor, ama dediğim gibi t bunları nasıl kullandığınıza bağlıdır. IoC'yi kullanıyorsanız doğru depoları enjekte edebilirsiniz.