Как преобразовать строки в столбцы в LINQ - PullRequest
1 голос
/ 09 мая 2019

У меня есть первый вывод на изображении, и я хочу преобразовать его во второй вывод на изображении, используя LINQ Core. Есть ли и прямая опция разворота в LINQ.

Я могу написать код для PIVOT и UNPIVOT в SQL. Но не могу найти способ сделать то же самое в LINQ.

У меня ниже SQL запрос для того же:

SELECT ResourceName,
            max(ENText)as ENText,
            max(FRText)as FRText,
            max(ZHText)as ZHText,
            max(DEText)as DEText,
            max(ITText)as ITText,
            max(JAText)as JAText,
            max(PTText)as PTText,
            max([PT-BRText]) as [PT-BRText],
            max(RUText) as RUText,
            max(ESText) as ESText,
            max(SVText) as SVText  into #temp 
            FROM   
GenericLanguageTranslation 
PIVOT  
(  
max(Translation) FOR LanguageID IN (
            ENText,
            ZHText,
            FRText,
            DEText,
            ITText,
            JAText,
            PTText,
            [PT-BRText],
            RUText,
            ESText,
            SVText)
) AS Tab2  
group by ResourceName
order by 1

select * from #temp
SELECT NEWID() as Id,ResourceName, [LanguageID],[Translation]-- into #GenericLanguageTranslation
FROM #temp
UNPIVOT
(
       [Translation]
       FOR [LanguageID] IN 
       (
            ENText,
            ZHText,
            FRText,
            DEText,
            ITText,
            JAText,
            PTText,
            [PT-BRText],
            RUText,
            ESText,
            SVText

       )
) AS UnpivotTranslation

enter image description here

1 Ответ

0 голосов
/ 09 мая 2019

Если вы хотите использовать рефлексию и хотите сделать разворот на стороне клиента, вот как это сделать.

Класс возврата включает в себя поля данных сводки и поля разворота:

public class UnpivotData {
    public Guid Id { get; set; }
    public string ResourceName { get; set; }
    public string LanguageID { get; set; }
    public string Translation { get; set; }

    public UnpivotData() => Id = Guid.NewGuid();

    public UnpivotData ShallowCopy() {
        var ans = (UnpivotData)this.MemberwiseClone();
        ans.Id = Guid.NewGuid();
        return ans;
    }
}

Затем метод расширения для разворота:

public static class IEnumerableExt {
    public static IEnumerable<UnpivotData> Unpivot<T>(this IEnumerable<T> src, string[] pivotFieldNames, string unPivotName, string unPivotValue, Func<string, bool> unpivotFieldNameFn) {
        var srcPIs = typeof(T).GetProperties();
        var srcPivotPIs = srcPIs.Where(pi => pivotFieldNames.Contains(pi.Name));
        var ansPIs = typeof(UnpivotData).GetProperties();
        var ansPivotPIs = ansPIs.Where(pi => pivotFieldNames.Contains(pi.Name));
        var srcAnsPivotPIs = srcPivotPIs.Zip(ansPivotPIs, (spi, api) => new { spi, api }).ToList();
        var srcUnpivotPIs = srcPIs.Where(pi => unpivotFieldNameFn(pi.Name)).ToList();
        var unPivotNamePI = ansPIs.First(pi => pi.Name == unPivotName);
        var unPivotValuePI = ansPIs.First(pi => pi.Name == unPivotValue);

        foreach (var d in src) {
            var ansbase = new UnpivotData();
            foreach (var sapi in srcAnsPivotPIs)
                sapi.api.SetValue(ansbase, sapi.spi.GetValue(d));

            foreach (var spi in srcUnpivotPIs) {
                var ans = ansbase.ShallowCopy();
                unPivotNamePI.SetValue(ans, spi.Name);
                unPivotValuePI.SetValue(ans, spi.GetValue(d));

                yield return ans;
            }
        }
    }
}

И теперь вы можете отменить вывод данных:

var result = genericLanguageTranslation.AsEnumerable().Unpivot(new[] { "ResourceName" }, "LanguageID", "Translation", fn => fn.EndsWith("Text"));
...