繁体   English   中英

处置上下文后,如何从实体框架(数据库优先)返回包含导航属性的模型?

[英]How do I return a Model from Entity Framework (Database First) that includes the Navigation Properties after the context is disposed?

实际上,我要问的内容比问题标题要宽得多……但这是一个特定的问题。

我正在尝试精简控制器,并将与Entity Framework的所有业务逻辑/交互都移入服务层,以使控制器根本不需要上下文,我认为这是做事的“正确”方法。

问题在于,当我创建一个返回域模型的服务层方法时,它不包含导航属性,并且一旦我在控制器中调用此方法并需要访问这些导航属性,就已经处理了上下文。 然后,这迫使我对其他服务层方法进行多次调用,以获取所需的其余属性,以便可以创建视图模型。

我确定问题是我没有以正确的方式创建我的方法,或者缺少针对这种情况的正确体系结构的某些组件,因此这里有一些代码来演示我在做什么。

服务层方法:

        public IEnumerable<Paper> GetPapersForReview(int userID, string courseID, string role)
        {
            using (USGEntities context = new USGEntities())
            {
                IEnumerable<Paper> models = (from a in context.Papers
                                             join b in context.Users_Roles on a.Paper_Types.Course_ID equals b.Course_ID
                                             where a.Status == "REV" && a.Deleted == false && b.User_ID == userID && b.Role.Name == role && b.Course_ID == courseID
                                             select a).ToList();

                return models;
            }
        }

控制器方式:

        public JsonResult GetPapersForReview(string courseID)
        {
            int user_id = new User().GetUserIDByDomainAccount(User.Identity.Name);

            var vm = (from a in new PaperService().GetPapersForReview(user_id, courseID, "Reviewer")
                      select new PaperViewModel()
                      { 
                          Paper_ID = a.ID,
                          Proposal_ID = a.Proposal_ID,
                          Expected_Start_Date = a.Expected_Start_Date
                      }).Distinct().ToList();

            foreach (var paper in vm)
            {
                Proposal proposal = new ProposalService().GetProposal(paper.Proposal_ID);
                Paper_Types paper_type = new PaperTypeService().GetPaperTypeByPaper(paper.Paper_ID);
                paper.Paper_Type = paper_type.Description;
                paper.Resources = new PaperService().GetResourceList(paper.Paper_ID);
                paper.Proposal_Title = proposal.Title;
                paper.Author = new UserService().GetNameByUserID(proposal.Author_User_ID);
            }

            return Json(vm, JsonRequestBehavior.AllowGet);
        }

因此,您可以在调用Service Layer方法并获得可以直接访问的属性后看到,然后我必须循环遍历该过程,并进行其他调用以获取我需要的其余属性。 我知道这不是正确的做事方式。 那么,如何更好地构造事物以从服务层返回我需要的一切呢?

其他一些相关的问题是:我应该从服务层返回IEnumerables还是其他东西,是否需要在两个地方都调用ToList()?

您具有.Include扩展名:

public IEnumerable<Paper> GetPapersForReview(int userID, string courseID, string role)
{
    using (USGEntities context = new USGEntities())
    {
        var result = context.Papers
            .Include(paper => paper.User)
            .Where(paper => paper.Status == "REV" && paper.Deleted == false && paper.User_ID == userID && paper.User.Role.Name == role && paper.Course_ID == courseID)
            .ToList();
        return result;
    }
}

您甚至可以使用.ThenInclude如果您具有多个级别):

.Include(p => p.Item)
    .ThenInclude(p => p.SubItem)

暂无
暂无

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

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