简体   繁体   English

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

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

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. 然后,这迫使我对其他服务层方法进行多次调用,以获取所需的其余属性,以便可以创建视图模型。

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. 因此,您可以在调用Service Layer方法并获得可以直接访问的属性后看到,然后我必须循环遍历该过程,并进行其他调用以获取我需要的其余属性。 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? 那么,如何更好地构造事物以从服务层返回我需要的一切呢?

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()?

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)

暂无
暂无

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

相关问题 如何在 Entity Framework 6 Database First 中对导航属性实现乐观并发 - How to implement optimistic concurrency on navigation properties in Entity Framework 6 Database First 如何阻止MVC4 ApiController序列化实体框架导航属性? - How do I prevent an MVC4 ApiController from serializing Entity Framework Navigation Properties? 包含导航属性时,如何阻止 Entity Framework Core 创建“自引用循环”? - How do I stop Entity Framework Core from creating “Self Referencing Loops” when including navigation properties? 实体框架6.1:代码优先导航属性没有在数据库中定义的对应键 - Entity Framework 6.1: Code First navigation properties that do not have corresponding keys defined in database 数据库优先方法缺少实体框架导航属性 - Entity Framework navigation properties missing in DataBase first approach 使用 Entity Framework 6.1 和 MVC 5 从数据库使用 Code First 后如何同步模型? - How to sync model after using Code First from Database using Entity Framework 6.1 and MVC 5? 如何编写测试以验证实体框架数据库第一模型 - How do I write a test to verify Entity Framework Database First Model 使用 Entity Framework Core 数据库优先方法如何将我的实体与基础设施层分开? - With Entity Framework Core database first approach how do I separate my entity from infrastructure layer? 实体框架上下文和 model inheritance 在数据库第一种方法中搭建脚手架时 - Entity Framework context and model inheritance when scaffolding in database first approach 如何通过实体框架更改数据库项的属性? - How do I change the properties of database item through Entity Framework?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM