Repository Generic

时间:2015-10-06 08:31:50

标签: c# entity-framework

I was trying to fix the structure of a generic repository.

I'm trying to understand how I can use a method that returns every time the correct repository.

I have a window of invoicing, each invoice type is saved on a different table. So I created a generic repository. for now I have created a method to return me the repository for the type of invoice.

This is the code of my generic repository:

public class RepositoryBase<T> where T : class,IEntityBase
{
    private readonly DbSet<T> ctx;
    internal DbContext context;
    private readonly UtilityDomain utilityDomain;

    public RepositoryBase(DbContext _context)
    {
        context = _context;
        ctx = _context.Set<T>();
        utilityDomain = new UtilityDomain();
    }


    public void Aggiungi(T oggetto)
    {
        ctx.Add(oggetto);

    }

   public void Elimina(Expression<Func<T, bool>> predicate)
    {
        var entityToDelete = ctx.Where(predicate);
        if (entityToDelete.Count() != 0)
        {
            foreach (var entity in entityToDelete)
            {
                ctx.Remove(entity);
            }
        }
    }      public T Prendi(Expression<Func<T, bool>> predicate)
    {
        var trovato = ctx.FirstOrDefault(predicate);
        return trovato;
    }

    public T PrendiPerId(Guid id)
    {
        return ctx.Find(id);
    }
    public T PrendiPerId(Guid id,string corpo1,string corpo2,string corpo3)
    {
        return ctx.Include(corpo1).Include(corpo2).Include(corpo3).FirstOrDefault(x=>x.Id == id);
    }
}


public interface IEntityBase
{
    Guid Id { get; set; }
    int NumeroRecord { get; set; }
    int NumeroRiga { get; set; }
    string Codice { get; set; }
    DateTime DataCreazione { get; set; }
    DateTime DataModifica { get; set; }
    string UsernameLogin { get; set; }
    string DatabaseLogin { get; set; }
    string NomePcLogin { get; set; }
    string CodiceDittaAssociata { get; set; }
    string RagioneSocialeDittaAssociata { get; set; }
}

The following is my class that should return the appropriate repository depending on the type the invoice:

public static class DocumentoMerceHelper
{
    public static dynamic RepositoryDocumenti(string _tipo4, dynamic nuovoCtx)
    {
           switch (_tipo4)
        {
            case "VFI":
                return new RepositoryBase<TestataFatturaImmediataVendita>(nuovoCtx);
            case "VDT":
                return new RepositoryBase<TestataDocumentoDiTrasportoVendita>(nuovoCtx);
            case "VFD":
                return new RepositoryBase<TestataFatturaDifferitaVendita>(nuovoCtx);
            case "VNC":
                return new RepositoryBase<TestataNotaCreditoGenericaVendita>(nuovoCtx);
            case "VNG":
                return new RepositoryBase<TestataNotaCreditoGenericaVendita>(nuovoCtx);
            case "VBU":
                return new RepositoryBase<TestataBuonoDiConsegnaVendita>(nuovoCtx);
        }
    }
}

Right now I do return a dynamic object, but this way I can not access all methods of the repository, for example the method "Elimina" method or the "Prendi" where I spend a predicate, because obviously in ViewModel it tells me that I cannot use a lambda expression to a dynamic object.

This is a method where my ViewModel calls the class that should give me back the appropriate repository:

private void AggiornaIdDocumentoAcquistoInFatturaVendita(string _tipo4,Guid? _idDocumentoVendita)
    {
        var newCtx = RitornaNuovoContesto();

        var repositoryDocumento = DocumentoMerceHelper.RepositoryDocumenti(_tipo4, newCtx);
        var documento = repositoryDocumento.Prendi(x => x.Id == _idDocumentoVendita);
}

I here by mistake because I can not use a lambda expression to a dynamic object.

How could I solve this?

2 个答案:

答案 0 :(得分:0)

If you are going for repository pattern go for unit of work, why? it adds abstraction layer and its shines when you need to do multiple table inserts or operation, normally you need to maintain transaction scope but now with unitofwork you dont need to handle that manually coz database context class is shared by all of them.

public class UnitOfWork : IDisposable
    {
        private DbContext context = new DbContext();
        private RepositoryBase<TestataFatturaImmediataVendita> testataFatturaImmediataVenditaRepository;
        private RepositoryBase<TestataFatturaImmediataVendita1> testataFatturaImmediataVenditaRepository1;
        continued......

        public GenericRepository<TestataFatturaImmediataVendita> testataFatturaImmediataVenditaRepository
        {
            get
            {

                if (this.testataFatturaImmediataVenditaRepository == null)
                {
                    this.testataFatturaImmediataVenditaRepository = new RepositoryBase<TestataFatturaImmediataVendita>(context);
                }
                return testataFatturaImmediataVenditaRepository;
            }
        }

        public void Save()
        {
            context.SaveChanges();
        }

        private bool disposed = false;

        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    context.Dispose();
                }
            }
            this.disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

OR

If you want to stick with it use a generic DocumentoMerceHelper, or create a a simple factory but instead of factory go for unit of work.

For more info regarding above defined repo pattern:

  1. http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application

答案 1 :(得分:0)

我要保存数据的表是相同的,都来自一个类。我正在尝试创建一个类,我返回适当的存储库以避免在操作期间的任何时候crud有各种情况: 我的ViewModel中的方法Elimina:

if (_tipo4 == "VFI")
        {
            testataFatturaImmediataVenditaRepository.EliminaPerId(_idTestata);
        }
        if (_tipo4 == "VDT")
        {
            testataDocumentoDiTrasportoRepository.EliminaPerId(_idTestata);
        }
        if (_tipo4 == "VFD")
        {
            testataFatturaDifferitaVenditaRepository.EliminaPerId(_idTestata);
        }
        if (_tipo4 == "VNC")
        {
            testataNotaCreditoVenditaRepository.EliminaPerId(_idTestata);
        }
        if (_tipo4 == "VNG")
        {
            testataNotaCreditoGenericaVenditaRepository.EliminaPerId(_idTestata);
        }
        if (_tipo4 == "VND")
        {
            testataNotaDebitoVenditaRepository.EliminaPerId(_idTestata);
        }
        if (_tipo4 == "VBU")
        {
            testataBuonoDiConsegnaVenditaRepository.EliminaPerId(_idTestata);
        }
        if (_tipo4 == "VFG")
        {
            testataFatturaGenericaVenditaRepository.EliminaPerId(_idTestata);
        }
        if (_tipo4 == "VFA")
        {
            testataFatturaAccontoVenditaRepository.EliminaPerId(_idTestata);
        }
        if (_tipo4 == "AFI")
        {
            testataFatturaImmediataAcquistoRepository.EliminaPerId(_idTestata);
        }
        if (_tipo4 == "ADT")
        {
            testataDocumentoDiTrasportoAcquistoRepository.EliminaPerId(_idTestata);
        }
        if (_tipo4 == "AFD")
        {
            testataFatturaDifferitaAcquistoRepository.EliminaPerId(_idTestata);
        }
        if (_tipo4 == "ACV")
        {
            testataContoVenditaRepository.EliminaPerId(_idTestata);
        }
        if (_tipo4 == "ANC")
        {
            testataNotaCreditoAcquistoRepository.EliminaPerId(_idTestata);
        }
        if (_tipo4 == "ANG")
        {
            testataNotaCreditoGenericaAcquistoRepository.EliminaPerId(_idTestata);
        }
        if (_tipo4 == "AND")
        {
            testataNotaDebitoAcquistoRepository.EliminaPerId(_idTestata);
        }
        if (_tipo4 == "ABU")
        {
            testataBuonoDiConsegnaAcquistoRepository.EliminaPerId(_idTestata);
        }
        if (_tipo4 == "AFG")
        {
            testataFatturaGenericaAcquistoRepository.EliminaPerId(_idTestata);
        }
        if (_tipo4 == "AAF")
        {
            testataAutofatturaRepository.EliminaPerId(_idTestata);
        }
        if (_tipo4 == "AFA")
        {
            testataFatturaAccontoAcquistoRepository.EliminaPerId(_idTestata);
        }
        if (_tipo4 == "ARM")
        {
            testataRicezioneMerceRepository.EliminaPerId(_idTestata);
        }
        if (_tipo4 == "ARI")
        {
            testataRimanenzeInizialiRepository.EliminaPerId(_idTestata);
        }

我的ViewModel中的方法Ricerca:

if (_tipo4 == "VFI")
        {
            _selectedItem = testataFatturaImmediataVenditaRepository.Prendi(x => x.Id == _idDocumentoRicerca, "CorpoFatturaImmediataVendita");
            newTestata = Mapper.Map<TestataFatturaImmediataVendita, TestataDocumento>(
                    (TestataFatturaImmediataVendita)_selectedItem);
        }
        if (_tipo4 == "VDT")
        {
            _selectedItem = testataDocumentoDiTrasportoRepository.Prendi(x => x.Id == _idDocumentoRicerca, "CorpoCorpoDocumentoDiTrasportoVendita");
            newTestata =
                Mapper.Map<TestataDocumentoDiTrasportoVendita, TestataDocumento>(
                    (TestataDocumentoDiTrasportoVendita)_selectedItem);
        }
        if (_tipo4 == "VFD")
        {
            _selectedItem = testataFatturaDifferitaVenditaRepository.Prendi(x => x.Id == _idDocumentoRicerca, "CorpoFatturaDifferitaVendita");
            newTestata =
                Mapper.Map<TestataFatturaDifferitaVendita, TestataDocumento>(
                    (TestataFatturaDifferitaVendita)_selectedItem);
        }
        if (_tipo4 == "VNG")
        {
            _selectedItem = testataNotaCreditoGenericaVenditaRepository.Prendi(x => x.Id == _idDocumentoRicerca, "CorpoNotaCreditoGenericaVendita");
            newTestata =
                Mapper.Map<TestataNotaCreditoGenericaVendita, TestataDocumento>(
                    (TestataNotaCreditoGenericaVendita)_selectedItem);
        }
        if (_tipo4 == "VBU")
        {
           _selectedItem = testataBuonoDiConsegnaVenditaRepository.Prendi(x => x.Id == _idDocumentoRicerca, "CorpoBuonoDiConsegnaVendita");
            newTestata =
                Mapper.Map<TestataBuonoDiConsegnaVendita, TestataDocumento>(
                    (TestataBuonoDiConsegnaVendita)_selectedItem);
        }
        if (_tipo4 == "VND")
        {
            _selectedItem = testataNotaDebitoVenditaRepository.Prendi(x => x.Id == _idDocumentoRicerca, "CorpoNotaDebitoVendita");
            newTestata =
               Mapper.Map<TestataNotaDebitoVendita, TestataDocumento>(
                    (TestataNotaDebitoVendita)_selectedItem);
        }
        if (_tipo4 == "VFG")
        {
            _selectedItem = testataFatturaGenericaVenditaRepository.Prendi(x => x.Id == _idDocumentoRicerca, "CorpoFatturaGenericaVendita");
            newTestata =
                Mapper.Map<TestataFatturaGenericaVendita, TestataDocumento>(
                    (TestataFatturaGenericaVendita)_selectedItem);
        }
        if (_tipo4 == "VNC")
        {
            _selectedItem = testataNotaCreditoVenditaRepository.Prendi(x => x.Id == _idDocumentoRicerca, "CorpoNotaCreditoVendita");
            newTestata = Mapper.Map<TestataNotaCreditoVendita, TestataDocumento>(
                    (TestataNotaCreditoVendita)_selectedItem);
        }
        if (_tipo4 == "VFA")
        {
            _selectedItem = testataFatturaAccontoVenditaRepository.Prendi(x => x.Id == _idDocumentoRicerca, "CorpoFatturaAccontoVendita");
            newTestata =
                Mapper.Map<TestataFatturaAccontoVendita, TestataDocumento>(
                   (TestataFatturaAccontoVendita)_selectedItem);
        }
        if (_tipo4 == "AFI")
        {
            _selectedItem = testataFatturaImmediataAcquistoRepository.Prendi(x => x.Id == _idDocumentoRicerca, "CorpoFatturaImmediataAcquisto");
            newTestata =
                Mapper.Map<TestataFatturaImmediataAcquisto, TestataDocumento>(
                    (TestataFatturaImmediataAcquisto)_selectedItem);
        }

每次我必须重复这些文档类型的所有案例。 为此,我试图创建一个重复它们的类,我的类返回正确的存储库。