简体   繁体   English

实体框架核心 Lambda 表达式连接 4 个表并使用 where 进行过滤

[英]Entity Framework Core Lambda Expression join 4 tables and filter with where

I have six tables as shown below.我有六个表,如下所示。 I am trying to get data based on Application_name , Environment_name , and Status .我正在尝试根据Application_nameEnvironment_nameStatus获取数据。

Status table:状态表:

Id, Name

Application table:申请表:

Id, Name

Servers table:服务器表:

Id, ServerName, Status

Environments table:环境表:

Id, Name

ResourceGroup table:资源组表:

Id, Name, Application_Id, Environment_Id

ServersResourceGroup:服务器资源组:

Id, Server_Id, Resource_Id

What I am trying to do is join all the require table and use where to filter data by Application_name , Environment_name , and Status我想要做的是加入所有 require 表并使用 where 来过滤数据Application_nameEnvironment_nameStatus

Here is my query I built, which returns all the data back by filtering Application_name but I am no way near to fulfill above requirement by adding additional filters by Environment_name and Status :(这是我构建的查询,它通过过滤Application_name返回所有数据,但我无法通过添加Environment_nameStatus额外过滤器来满足上述要求:(

So below is the query that returns all the data with Application_name所以下面是返回带有Application_name所有数据的查询

public IEnumerable<ResourceGroup> GetAllServersByApplication(string application_name, string environment_name, string status)
{
    var query = _context.ResourceGroup
            .Include(a => a.Application)
            .Include(t => t.Type)
            .Include(e => e.ServersGroup).ThenInclude(e => e.Environment)
            .Include(s => s.ServersGroup).ThenInclude(s => s.Server)
            .Include(s => s.ServersGroup).ThenInclude(s => s.Server).ThenInclude(s => s.Status)
            .Where(a => a.Application.Name == application_name)
            .ToList();

    return query;
}

Here is the query that I am trying to write that will filter based on all three filters:这是我尝试编写的查询,它将基于所有三个过滤器进行过滤:

    public IEnumerable<ResourceGroup> GetAllServersByApplication(string application_name, string environment_name, string status)
    {
        var query = _context.ResourceGroup
            .Include(a => a.Application)
            .Include(t => t.Type)
            .Include(e => e.ServersGroup).ThenInclude(e => e.Environment)
            .Include(s => s.ServersGroup).ThenInclude(s => s.Server)
            .Include(s => s.ServersGroup).ThenInclude(s => s.Server).ThenInclude(s => s.Status)
            .Where(a => a.Application.Name == application_name)
            .Select(e => e.ServersGroup.Where(s => s.Environment.Name == environment_name && s.Server.Status.Name == status)
            .ToList();

        return query;
    }

I get a red line under return query .我在return query下看到一条红线。 Please see below image:请看下图: 在此处输入图片说明

Is there any easier way to write lambda query then what I am trying to do?有没有更简单的方法来编写 lambda 查询然后我想要做什么?

Any help is really appreciated.任何帮助都非常感谢。 :) :)

Thanks,谢谢,

Ray射线

There error is because you are now returning an collection of ServersGroup which is different than in your method signature.出现错误是因为您现在正在返回与您的方法签名不同的ServersGroup集合。 This is due to the fact that you added a Select clause and selected property ServersGroup from ResourceGroup .这是因为您添加了 Select 子句并从ResourceGroup选择了属性ServersGroup Filtering should happen in the Where clause.过滤应该发生在Where子句中。 I updated the code below and moved your filter in the Select to the Where , also the included where was changed to an Any as a Where expects boolean clauses.我更新了下面的代码,并将Select中的过滤器移动到Where ,也将包含的 where 更改为Any作为 Where 期望布尔子句。

If it was your intention to only include certain ServersGroup within your ResourceGroup then you should filter those out in a join or outer join statement.如果您打算只在您的ResourceGroup包含某些ServersGroup ,那么您应该在连接或外部连接语句中过滤掉那些。

Also you probably do not need Include's everywhere.此外,您可能不需要到处都包含。 Includes are used for eager loading which ensures that only one roundtrip is necessary to the database to get the associated relationships.包含用于急切加载,以确保数据库只需要一次往返即可获取关联关系。 If you do not plan on accessing all these related properties then do not include them.如果您不打算访问所有这些相关属性,则不要包含它们。

I do assume that your relationships are mapped correctly either in fluent mapping files or using attributes on the models.我确实假设您的关系在流畅的映射文件中或使用模型上的属性正确映射。

public IEnumerable<ResourceGroup> GetAllServersByApplication(string application_name, string environment_name, string status)
{
    var query = _context.ResourceGroup
        .Include(a => a.Application)
        .Include(t => t.Type)
        .Include(e => e.ServersGroup).ThenInclude(e => e.Environment)
        .Include(s => s.ServersGroup).ThenInclude(s => s.Server)
        .Include(s => s.ServersGroup).ThenInclude(s => s.Server).ThenInclude(s => s.Status)
        .Where(a => a.Application.Name == application_name && a.ServersGroup.Any(s => s.Environment.Name == environment_name && s.Server.Status.Name == status))
        .ToList();

    return query;
}

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

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