【问题标题】:What is the best solution to move complex queries from controller into repository?将复杂查询从控制器移动到存储库的最佳解决方案是什么?
【发布时间】:2016-08-21 12:00:51
【问题描述】:

在创建我的应用程序期间,我将 Model layerRepository layer 扔到了单独的项目中。我的应用程序中的每个表单都由其自己的ViewModel class 表示。所有ViewModel classes 都存储在MyApplicationName.Web 的文件夹ViewModels 中。在GET requestMyDrafts 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吗?谢谢。

【问题讨论】:

    标签: c# asp.net-mvc


    【解决方案1】:

    您的方法是正确的,将查询移动到单独的 repo 项目中。但是MyApplicationName.Repository 不应该知道你的 web 项目,也不应该知道你的视图模型。它应该只适用于您的域模型。所以我建议你的选择是在你的域和视图模型之间使用一些映射工具,比如AutoMapper。 我认为这可以解决您的架构问题。

    【讨论】:

      猜你喜欢
      • 2022-12-19
      • 1970-01-01
      • 2019-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多