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

时间:2021-11-11 02:22:11

What I am asking is actually a little more broad than the question title...but that is kind of the specific question.

我问的实际上比问题标题更广泛......但这是一个具体的问题。

I am trying to thin out my controllers and move all business logic / interaction with Entity Framework into a Service Layer so that my controllers don't need the context at all, which I believe is the "right" way to do things.

我正在尝试将我的控制器稀释并将所有业务逻辑/与Entity Framework的交互转移到服务层,以便我的控制器根本不需要上下文,我认为这是“正确”的做事方式。

The problem is that when I create a Service Layer method that returns a domain model, it does not contain the Navigation Properties and once I am calling this method in my controller and need to access these navigation properties, the context has already been disposed. This then forces me to make multiple calls out to other Service Layer methods to get the rest of the properties I need so that I can create my View Model.

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

I'm sure the issue is that I am not creating my methods in the proper way or missing some component of the correct architecture for this situation so here is some code to demonstrate what I am doing.

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

Service Layer method:

服务层方法:

        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;
            }
        }

Controller method:

控制器方法:

        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);
        }

So you can see after I make the call to the Service Layer method and get the properties that I have direct access to, I then have to loop back through that and make additional calls to get the rest of the properties that I need. I know this is not the right way to do things. So how do I structure things better to return everything I need from the Service Layer?

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

Some other related questions are: should I be returning IEnumerables or something else from the Service Layer and do I need to be calling ToList() in both places?

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

1 个解决方案

#1


4  

You have the .Include extension:

你有.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;
    }
}

You can even use .ThenInclude if you have multiple levels:

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

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

#1


4  

You have the .Include extension:

你有.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;
    }
}

You can even use .ThenInclude if you have multiple levels:

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

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