简体   繁体   English

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

[英]selecting properties from other table with Lambda expression

I am less experienced with Lambda expression for .NET and trying to get data from SQL using lambda expression. 我对.NET的Lambda表达式以及尝试使用Lambda表达式从SQL获取数据的经验较少。 With below query, I am able to get data back, but do not want to use include to get all properties from other tables. 通过下面的查询,我能够取回数据,但不想使用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;
}

Lets take an example of below include statement. 让我们以下面的include语句为例。

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

From s.Server , I only want to select Id,ServerName,Status, and IPAddress . s.Server ,我只想选择Id,ServerName,Status, and IPAddress These are the properties from Servers class that I created as a model. 这些是我作为模型创建的Servers类的属性。

What is the easy way to exclude all the includes and only show properties that I am interested in? 排除所有包含项并仅显示我感兴趣的属性的简单方法是什么?

Here are my tables and its properties: 这是我的表及其属性:

Status table: 状态表:

Id, Name

Application table: 申请表:

Id, Name

Servers table: 服务器表:

Id, ServerName, Status

Environments table: 环境表:

Id, Name

ResourceGroup table: ResourceGroup表:

Id, Name, Application_Id, Environment_Id

ServersResourceGroup table: ServersResourceGroup表:

Id, Server_Id, Resource_Id

UPDATE 1 : 更新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;

And error from red line on query variable: 并且来自query变量上红线的错误: 在此处输入图片说明

UPDATE 2 : 更新2

Here is the query syntax: 这是查询语法:

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;

Here is the red line error I get in query variable: 这是查询变量中出现的红线错误:

在此处输入图片说明

Your help is really appreciated. 非常感谢您的帮助。 :) :)

Thanks, 谢谢,

Ray 射线

With lambda expressions, you can use SelectMany to flatten 1-n associations into a 1 dimensional list (ie parent and child properties side-by-side). 使用lambda表达式,您可以使用SelectMany将1-n关联展平为一维列表(即,父和子属性并排)。 In your case, judging from the Where clause, I think only ResourceGroup - ServerGroup is 1 - n, so it should be something like: 从您的情况来看,从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.
                                  })
                     )

Of course it's good to know how to use lambda expressions, but there's really no point in using them when query syntax makes for much better comprehensible code. 当然,知道如何使用lambda表达式是很好的选择,但是当查询语法可以提供更好的可理解代码时,使用它们真的没有意义。

The equivalent in query syntax is: 查询语法中的等效项是:

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

As you see - 正如你看到的 -

  • n - 1 associations are represented by a let statement (which really only helps here to shorten the references in the select ) n-1个关联由let语句表示(这实际上仅有助于缩短select的引用)
  • 1-n associations are represented by the from ... from syntax, which is query syntax for SelectMany . 1-n关联由from ... from语法表示,它是SelectMany查询语法。

I didn't change the Where clause in the query syntax. 我没有更改查询语法中的Where子句。 Maybe you can use ... 也许你可以使用...

            where app.Name == application_name
               && env.Name == environment_name
               && stat.Name == status)

... but note that this is different. ...但是请注意,这是不同的。 The original where returns all ResourceGroup having at least one ServerGroup meeting the condition (and maybe other groups with different environments and statuses). 原始where返回所有具有至少一个满足条件的ServerGroup所有ResourceGroup (以及可能具有不同环境和状态的其他组)。 The other where only returns data with environments and statuses equal to the search parameters. 其他where只能用环境返回数据和状态等于搜索参数。

Don't Include all the related tables, but Select all the fields you need. 不要Include所有相关表,而是Select所有字段。 You might find it easier to make a new class to hold the data. 您可能会发现创建一个新类来保存数据更加容易。

Sorry if I can't make a real query statement here, but your question doens't specify the fields you need. 抱歉,如果我无法在此处做出真实的查询语句,但您的问题未指定您需要的字段。

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

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