将复杂查询从控制器移动到存储库的最佳解决方案是什么?

时间:2016-04-27 09:23:00

标签: c# asp.net-mvc

在创建我的应用时,我将Model layerRepository layer投放到单独的项目中。我的应用中的每个表单都由自己的ViewModel class表示。所有ViewModel classes都存储在MyApplicationName.Web中的文件夹ViewModels中。在GET request MyDrafts form期间,会启动以下功能:

public ActionResult MyDrafts()
        {
            MyDraftsVM dataVM = GetDataMyDrafts();
            return View(dataVM);
        }


        private MyDraftsVM GetDataMyDrafts()
        {        
            MyDraftsVM dataVM = new MyDraftsVM();

            using (var context = new PrincipalContext(ContextType.Domain))
            {
                List<MyDraftsVM.MyDraftVM> userInvoices = new List<MyDraftsVM.MyDraftVM>();
                userInvoices = _repoExhibitor.Context.Exhibitors
                                                .Join(_repoExhibitor.Context.Invoices.Where(x => x.CreatedBy == User.Identity.Name && x.Status == (int)(ModelEnums.Invoice.Status.Przygotowanie)),
                                                e => e.Id,
                                                i => i.Id,
                                                (e, i) => new { e, i })
                                                .ToList()
                                                .Select(s => new MyDraftsVM.MyDraftVM(s.e, s.i, UserPrincipal.FindByIdentity(context, s.i.CreatedBy).DisplayName))
                                                .ToList();

                List<MyDraftsVM.MyDraftVM> userCorrespondence = new List<MyDraftsVM.MyDraftVM>();
                userCorrespondence = _repoExhibitor.Context.CorrespondenceSenders
                                                    .Join(_repoExhibitor.Context.Correspondences.Where(x => x.CreatedBy == User.Identity.Name && x.Status == (int)(ModelEnums.Invoice.Status.Przygotowanie)),
                                                    sen => sen.Id,
                                                    c => c.Id,
                                                    (sen, c) => new { sen, c })
                                                    .ToList()
                                                    .Select(s => new MyDraftsVM.MyDraftVM(s.c, UserPrincipal.FindByIdentity(context, s.c.CreatedBy).DisplayName))                                                 
                                                    .ToList();                                                    

                dataVM.Documents.AddRange(userInvoices);
                dataVM.Documents.AddRange(userCorrespondence);
            }
            return dataVM;
        }

MyDraftsVM类如下所示:

public class MyDraftsVM
    {
        public MyDraftsVM()
        {
            this.Documents = new List<MyDraftVM>();
            this.Layout = "~/Views/Shared/_LayoutBox.cshtml";
        }

        public List<MyDraftVM> Documents { get; set; }
        /// <summary>
        /// layout path
        /// </summary>      
        public string Layout { get; set; }

        public class MyDraftVM
        {


            public MyDraftVM()
            {
                this.DocumentPartial = new DocumentMemebership();
                this.InvoicePartial = new InvoiceMembership();
                this.ExhibitorPartial = new ExhibitorMembership();
                this.CorrespondencePartial = new CorrespondenceMembership();
            }

            public MyDraftVM(Exhibitor e, Invoice i, string createdBy)
            {              
                InvoicePartial = Mapper.Map<MyDraftsVM.MyDraftVM.InvoiceMembership>(i);
                ExhibitorPartial = Mapper.Map<MyDraftsVM.MyDraftVM.ExhibitorMembership>(e);
                DocumentPartial = new MyDraftsVM.MyDraftVM.DocumentMemebership()
                {
                    DocumentType = "Invoice",
                    Number = i.InvoiceNumber,
                    IssuingDate = i.IssuingDate,
                    CreatedBy = createdBy
                };
            }

            public MyDraftVM(Correspondence c, string createdBy)
            {
                CorrespondencePartial = Mapper.Map<MyDraftsVM.MyDraftVM.CorrespondenceMembership>(c);
                DocumentPartial = new MyDraftsVM.MyDraftVM.DocumentMemebership()
                {
                    DocumentType = "Correspondence",
                    Number = c.Signature,
                    IssuingDate = c.IssuingDate,
                    CreatedBy = createdBy,
                };
            }

            public DocumentMemebership DocumentPartial { get; set; }
            public InvoiceMembership InvoicePartial { get; set; }
            public CorrespondenceMembership CorrespondencePartial { get; set; }
            public ExhibitorMembership ExhibitorPartial { get; set; }


            public class InvoiceMembership : InvoiceVM
            {
                public virtual int Id { get; set; }
            }


            public class CorrespondenceMembership : CorrespondenceVM
            {

            }


            public class ExhibitorMembership : ExhibitorVM
            {
            }


            public class DocumentMemebership : DocumentVM
            {
            }


        }

    }

我想将joins的复杂查询移到repository,此处出现问题。我将此问题称为“交互项目的问题”,因为项目MyApplicationName .Web已引用MyApplicationName.Repository。如果我想将查询移至MyApplicationName.Repository,我还必须移至MyDraftsVM object,属于MyApplicationName.Web。 我现在看到的唯一解决方案是将ViewModels文件夹作为单独的项目分开,并为此项目提供参考MyApplicationName.WebMyApplicationName.Repository。我不知道这是不是一个好主意,所以这就是我问你的原因。 如果这不是一个好主意,你能否给我更好的解决方案来将这些复杂的查询移到repository?谢谢。

1 个答案:

答案 0 :(得分:0)

你是在正确的方式,在单独的repo项目中移动查询。但var gErrorMsg = ""; function validateForm() { "use strict"; var isAllOK = false; gErrorMsg = ""; var dobOK = isDOBOK(); if (dobOK) { isAllOK = true; } else { alert(gErrorMsg); gErrorMsg = ""; isAllOK = false; } return isAllOK; } function isDOBOK(){ var validDOB = true; var now = new dob(); var dob = document.getElementById("dob").value; var dateMsg = ""; var dmy = dob.split("/"); var allNumbers = true; for (var i = 0; i < dmy.length; i++){ if(isNaN(dmy[i])){ dateMsg = dateMsg + "You must enter only numbers into the date" + "\n"; validDOB = false; } } if ((dmy[0] <1) || (dmy[0] > 31) { dateMsg = dateMsg + "Day must be between 1 and 31" + "\n"; validDOB = false; } if ((dmy[1] <1) || (dmy[0] > 12) { dateMsg = dateMsg + "Month must be between 1 and 12" + "\n"; validDOB = false; } if ((dmy[2] < now.getFullYear() - 80)) { dateMsg = dateMsg + "You must be younger than 80" + "\n"; validDOB = false; } if (!validDOB){ gErrorMsg = gErrorMsg + dateMsg; } return validDOB; } function init() { var regForm = document.getElementById("regForm"); regForm.onsumbit = validateForm; } window.onload = init; 不应该了解您的网络项目,也不了解您的视图模型。它应该只适用于您的域模型。因此,我建议您选择在您的域和AutoMapper等视图模型之间使用一些映射工具。 我认为这可以解决你的建筑问题。