簡體   English   中英

使用Lambda表達式從其他表中選擇屬性

[英]selecting properties from other table with Lambda expression

我對.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語句為例。

.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變量上紅線的錯誤: 在此處輸入圖片說明

更新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;

這是查詢變量中出現的紅線錯誤:

在此處輸入圖片說明

非常感謝您的幫助。 :)

謝謝,

射線

使用lambda表達式,您可以使用SelectMany將1-n關聯展平為一維列表(即,父和子屬性並排)。 從您的情況來看,從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語法表示,它是SelectMany查詢語法。

我沒有更改查詢語法中的Where子句。 也許你可以使用...

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

...但是請注意,這是不同的。 原始where返回所有具有至少一個滿足條件的ServerGroup所有ResourceGroup (以及可能具有不同環境和狀態的其他組)。 其他where只能用環境返回數據和狀態等於搜索參數。

不要Include所有相關表,而是Select所有字段。 您可能會發現創建一個新類來保存數據更加容易。

抱歉,如果我無法在此處做出真實的查詢語句,但您的問題未指定您需要的字段。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM