簡體   English   中英

將 T-SQL string_agg 轉換為 LINQ C#

[英]Converting T-SQL string_agg to LINQ C#

我正在嘗試將我的 T-SQL 查詢轉換為 LINQ。

我的查詢:

SELECT l.Id, s.SystemSerial, v.LicenseVersion, l.CreatedDate, STRING_AGG (sf.[Name], ',') as Features
FROM [system] AS s
LEFT OUTER JOIN SoftwareLicense AS l ON l.SystemId = s.id
LEFT OUTER JOIN SoftwareVersion as v ON l.SoftwareVersionId = v.Id
LEFT OUTER JOIN FeatureLicense as fl ON fl.SoftwareLicenseId = l.Id AND fl.IsActive = 1
LEFT OUTER JOIN SoftwareFeature as sf ON sf.Id = fl.SoftwareFeatureId
GROUP BY l.id, s.SystemSerial, v.LicenseVersion, l.CreatedDate

上面的查詢返回以下內容:

267     DELL-H99DHM2        1.0     2019-05-06T13:19:59.3081543     Advanced,Internal
270     DESKTOP-SLL5NLC     1.0     2019-05-06T19:22:19.5161704     Standard,Video
271     DESKTOP-T67FIK1     1.0     2019-05-06T19:30:50.6251582     Advanced,Internal,Video
272     DESKTOP-T67FIK1     1.1     2019-05-07T11:30:50.2351512     Advanced

我的原始 LINQ 查詢(在添加STRING_AGG之前)如下所示:

var allSystemsAndLicenses = (from s in _context.Systems
                            join sl in _context.SoftwareLicenses on s.Id equals sl.SystemId into sll
                            from sl2 in sll.DefaultIfEmpty()
                            join sv in _context.SoftwareVersions on sl2.SoftwareVersionId equals sv.Id into svv
                            from sv2 in svv.DefaultIfEmpty()
                            join fl in _context.FeatureLicenses on sl2.Id equals fl.SoftwareLicenseId into fll
                            from fl2 in fll.DefaultIfEmpty().Where(a => a.IsActive)
                            join sf in _context.SoftwareFeatures on fl2.SoftwareFeatureId equals sf.Id into sff
                            from sf2 in sff.DefaultIfEmpty()
                            select new SystemLicenseResult
                            {
                                LicenseId = sl2.Id,
                                SerialNumber = s.SystemSerial,
                                LicenseVersion = sv2.LicenseVersion + " (" + sv2.Software.Name + ")",
                                LicenseExpiryDate = sl2.CreatedDate,
                                CreatedDate = sl2.CreatedDate
                            });

我試圖弄清楚如何在我的 C# 代碼中將STRING_AGG (sf.[Name], ',') as Features作為 LINQ。 我有一種感覺,我需要使用 linq 的 GroupBy 功能或在選擇中進行某種選擇?

任何幫助表示贊賞。

我想我想通了! 我的代碼如下:

var allSystemsAndLicenses = (from s in _context.Systems
    join sl in _context.SoftwareLicenses on s.Id equals sl.SystemId into sll
    from sl2 in sll.DefaultIfEmpty()
    join sv in _context.SoftwareVersions on sl2.SoftwareVersionId equals sv.Id into svv
    from sv2 in svv.DefaultIfEmpty()
    join fl in _context.FeatureLicenses on sl2.Id equals fl.SoftwareLicenseId into fll
    from fl2 in fll.DefaultIfEmpty().Where(a => a.IsActive)
    join sf in _context.SoftwareFeatures on fl2.SoftwareFeatureId equals sf.Id into sff
    from sf2 in sff.DefaultIfEmpty()
    select new SystemLicenseResult
    {
        LicenseId = sl2.Id,
        SerialNumber = s.SystemSerial,
        LicenseVersion = sv2.LicenseVersion + " (" + sv2.Software.Name + ")",
        LicenseExpiryDate = sl2.CreatedDate,
        LicenseFeatures = sf2.Name,
        CreatedDate = sl2.CreatedDate
    });

// I have some predicates defined that I am not putting here, but they do exist.
var filteredResults = allSystemsAndLicenses.Where(predicates);

var groupedResult = filteredResults.GroupBy(a => a.LicenseId);
var result = groupedResult.ToList()
    // Because the ToList(), this select projection is not done in the DB
    .Select(eg => new SystemLicenseResult
        {
            LicenseId = eg.Key,
            SerialNumber = eg.First().SerialNumber,
            LicenseFeatures = string.Join(",", eg.Select(i => i.LicenseFeatures))
        })

這似乎返回與 T-SQL 語句相同的結果視圖!

請注意,這實際上並沒有轉換為 SQL STRING_AGG語法。 EF 拉取整個列表,然后在內存中聚合這些字符串。

這意味着,如果您的分組項目中有大量其他字段,並且有許多需要連接的子字符串,那么所有“分組”字段都將針對要連接的每個字符串重復。 即您的SerialNumberLicenseVersion等將根據LicenseFeature復制(檢查生成的 sql)。

這可能意味着大量額外的“重復”數據在您的數據庫服務器和 EF 客戶端之間移動。

如果這可能是一個問題(場景包含很少的分組字段,每個字段都有很多子字符串),請考慮將查詢拆分為 2 個單獨的查詢並在內存中手動連接。

在每個分組行只有幾個字符串的情況下,只有 1 次往返會更快。

暫無
暫無

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

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