使用Lambda表达式从其他表中选择属性

时间:2016-10-15 02:53:28

标签: c# asp.net-mvc linq lambda

我对.NET的Lambda表达式经验不足,并尝试使用lambda表达式从SQL获取数据。使用以下查询,我可以返回数据,但不想使用include从其他表中获取所有属性。

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

让我们举一个下面包括声明的例子。

.Include(s => s.ServersGroup).ThenInclude(s => s.Server)

s.Server开始,我只想选择Id,ServerName,Status, and IPAddress。这些是我作为模型创建的Servers类的属性。

排除所有包含的简单方法是什么,只显示我感兴趣的属性?

以下是我的表格及其属性:

状态表:

Id, Name

申请表:

Id, Name

服务器表:

Id, ServerName, Status

环境表:

Id, Name

ResourceGroup 表:

Id, Name, Application_Id, Environment_Id

ServersResourceGroup 表格:

Id, Server_Id, Resource_Id

更新1

var query = _context.ResourceGroup
                    .SelectMany(rg => rg.ServersGroup
                    .Select(sg => new
                    {
                        ResourceName = rg.Name,
                        ApplicationName = rg.Application.Name,
                        ServerName = sg.Server.ServerName,
                        EnvironmentName = sg.Environment.Name,
                        Status = sg.Server.Status.Name
                    })).Where(a => a.ApplicationName == application_name && a.EnvironmentName == environment_name && a.Status == status).ToList();
        return query;

query变量上的红线错误: enter image description here

更新2

以下是查询语法:

var query = from rg in _context.ResourceGroup
                    let app = rg.Application
                    from sg in rg.ServersGroup
                    let env = sg.Environment
                    let srv = sg.Server
                    let stat = srv.Status
                    where app.Name == application_name
                            && rg.ServersGroup.Any(s => s.Environment.Name == environment_name
                                      && s.Server.Status.Name == status)
                    select new
                    {
                        ResourceGroupName = rg.Name,
                        ApplicationName = app.Name,
                        ServerName = srv.ServerName,
                        Alias = srv.Alias,
                        IPAddress = srv.IPAddress,
                        Type = rg.Type.Name,
                        Status = stat.Name
                    };
        return query;

以下是我在查询变量中得到的红线错误:

enter image description here

非常感谢您的帮助。 :)

谢谢,

2 个答案:

答案 0 :(得分:1)

使用lambda表达式,您可以使用SelectMany将1-n关联展平为1维列表(即并排的父级和子级属性)。在您的情况下,从Where条款判断,我认为只有ResourceGroup - ServerGroup是1 - n,所以它应该是这样的:

var query = _context.ResourceGroup
                    .SelectMany
                     (
                          rg => rg.ServersGroup
                                  .Select(sg => new 
                                  {
                                      ResourceGroup = rg.Name,
                                      Application = rg.Application.Name,
                                      Server = sg.Server.ServerName,
                                      // etc.
                                  })
                     )

当然知道如何使用lambda表达式很有用,但是当查询语法产生更好的可理解代码时,使用它们真的没有意义。

查询语法中的等价物是:

var query = from rg in _context.ResourceGroup
            let app = rg.Application
            from sg in rg.ServersGroup
            let env = sg.Environment
            let srv = sg.Server
            let stat = srv.Status
            where app.Name == application_name
               && sg.ServersGroup.Any(s => s.Environment.Name == environment_name
                                        && s.Server.Status.Name == status)
            select new
            {
                ResourceGroup = rg.Name,
                Application = app.Name,
                Server = srv.ServerName,
                // etc. use any property from rg, app, sg, srv, stat
            };

如你所见 -

  • n - 1个关联由let语句表示(这实际上只能帮助缩短select中的引用)
  • 1-n关联由from ... from语法表示,SelectManyWhere的查询语法。

我没有更改查询语法中的 where app.Name == application_name && env.Name == environment_name && stat.Name == status) 子句。 也许你可以使用......

where

...但请注意,这是不同的。原始ResourceGroup会返回至少一个ServerGroup符合条件的所有where(可能还有其他具有不同环境和状态的组)。另一个import { Router, NavigationCancel } from '@angular/router'; import { URLSearchParams, } from '@angular/http'; 仅返回环境和状态等于搜索参数的数据。

答案 1 :(得分:0)

不要Include所有相关的表格,而是Select您需要的所有字段。您可能会发现创建一个新类来保存数据更容易。

很抱歉,如果我不能在此处发出真实的查询声明,但您的问题不会指定您需要的字段。