简体   繁体   English

通用仓库

[英]Repository Generic

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. 现在,我确实返回了一个动态对象,但是通过这种方式,我无法访问存储库的所有方法,例如,我使用谓词的方法“ Elimina”方法或“ Prendi”,因为显然在ViewModel中它告诉我不能对动态对象使用lambda表达式。

This is a method where my ViewModel calls the class that should give me back the appropriate repository: 这是我的ViewModel调用该类的方法,该类应该给我适当的存储库:

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. 我在这里是错误的,因为我不能对动态对象使用lambda表达式。

How could I solve this? 我该如何解决?

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. 当需要执行多个表插入或操作时,它增加了抽象层,并具有其亮点。通常,您需要维护事务范围,但是现在有了unitofwork,就不需要处理手动共享所有数据库上下文类的问题。

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 aa simple factory but instead of factory go for unit of work. 如果您要坚持使用它,请使用通用的DocumentoMerceHelper,或者创建一个简单的工厂,而不是工厂,而是使用工作单元。

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 http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-在asp-net-mvc应用程序中

the tables where i'm going to save the data are identical, all derive from a class. 我要保存数据的表是完全相同的,所有这些表都派生自一个类。 I'm trying to create me a class that I return the repository suitable to avoid any time during operations crud to have various cases: My Method Elimina in my ViewModel: 我正在尝试创建一个类,使我返回适合于避免在操作期间出现各种情况的任何时间的存储库的类:ViewModel中的My Method 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);
        }

My Method Ricerca in My ViewModel: 我的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);
        }

every time I have to repeat all the cases for those document types. 每次我必须针对这些文档类型重复所有情况时。 For this I am trying to make a class where repeat them once and I class returns the correct repository. 为此,我试图创建一个类,在其中重复一次,然后类返回正确的存储库。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM