将平面数据库行数据转换为嵌套类型化对象 linq

J E*_* EC 3 c# linq

我将 sql 外连接的结果作为 IEnumerable 中的平面结果获取,并希望将它们转换为 linq 中的嵌套类型对象。从这样的事情:

[{id: 1, industryId: 1}, {id:1, industryId: 2}, {id:2, industryId: 1} etc..]
Run Code Online (Sandbox Code Playgroud)

像这样的事情:

list of Company [{id: 1, list of Industry{industryId: 1, 2}, {id: 2, list of Industry{industryId: 1}}]
Run Code Online (Sandbox Code Playgroud)

我目前正在尝试使用 GroupBy 的解决方案:

Companies = flatDbRows
                .GroupBy(
                row => row.CompanyId,
                (key, value) => new CompanyModel
                {
                    CompanyId = value.First().CompanyId,
                    CompanyName = value.First().CompanyName,
                    Industries = value
                        .GroupBy(
                            row => new { row.IndustryId, row.Industry },
                            (k, v) => new IndustryModel() { IndustryId = k.IndustryId, Name = k.Industry }
                        )
                        .Where(x => x.IndustryId != 0)
                        .ToList(),
                }).ToList();
        }
Run Code Online (Sandbox Code Playgroud)

但感觉不太好,尤其是我用来获取仅属于每个集团公司的值的所有 value.First() 。还有更合适的吗?组加入听起来更像是我想要的,但我无法理解如何将其应用到单个列表。如果更简单的话,我愿意使用查询语法而不是 lambda。

我正在尝试从这个模型开始(其中公司相关信息将为每个外部连接的行业结果重复):

public class CompanyFlatDbRowsModel
{
    public int CompanyId { get; set; }
    public string CompanyName { get; set; }
    public int IndustryId{ get; set; }
    public string Industry { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

对此:

public class CompanyModel
{
    public int CompanyId { get; set; }
    public string CompanyName { get; set; }
    public IEnumerable<IndustryModel> Industries { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

M G*_*M G 5

// 提供模型后进行完整编辑

public class TestClass
{
    public class CompanyModel
    {
        public int CompanyId { get; set; }
        public string CompanyName { get; set; }
        public List<IndustryModel> Industires { get; set; }
    }

    public class IndustryModel
    {
        public int IndustryId { get; set; }
        public string IndustryName { get; set; }
    }

    public class CompanyFlatDbRowsModel
    {
        public CompanyFlatDbRowsModel()
        {
        }

        public int CompanyId { get; set; }
        public string CompanyName { get; set; }
        public int IndustryId { get; set; }
        public string Industry { get; set; }
    }

    [Fact]
    public void Test()
    {
        var data = new List<CompanyFlatDbRowsModel>
        {
            new CompanyFlatDbRowsModel
            {
                CompanyId = 1,
                CompanyName = "Company 1",
                IndustryId = 1,
                Industry = "Industry 1"
            },
            new CompanyFlatDbRowsModel
            {
                CompanyId = 1,
                CompanyName = "Company 1",
                IndustryId = 2,
                Industry = "Industry 2"
            },
            new CompanyFlatDbRowsModel
            {
                CompanyId = 2,
                CompanyName = "Company 2",
                IndustryId = 3,
                Industry = "Industry 3"
            },
            new CompanyFlatDbRowsModel
            {
                CompanyId = 2,
                CompanyName = "Company 2",
                IndustryId = 4,
                Industry = "Industry 4"
            },
        };

        var result = data.GroupBy(x => x.CompanyId)
            .Select(x => new CompanyModel()
            {
                CompanyId = x.Key,
                CompanyName = x.First().CompanyName,
                Industires = x.Select(y=> new IndustryModel
                {
                    IndustryName = y.Industry,
                    IndustryId = y.IndustryId
                }).ToList()
            }).ToList();

        foreach (var item in result)
        {
            var text = $"Company id : {item.CompanyId}, industries : {string.Join(',',item.Industires.Select(x=>$"(name: {x.IndustryName}, id: {x.IndustryId})"))}";
            Debug.WriteLine(text);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

Company id : 1, industries : (name: Industry 1, id: 1),(name: Industry 2, id: 2)
Company id : 2, industries : (name: Industry 3, id: 3),(name: Industry 4, id: 4)
Run Code Online (Sandbox Code Playgroud)

编辑:

或者,您可以执行以下操作,但是“第一件事”仍然发生在某个地方,我也尝试过 GroupJoin,但在这种情况下它并没有真正的帮助。

    var otherResult = data.Select(x =>
        new CompanyModel
        {
            CompanyId = x.CompanyId,
            CompanyName = x.CompanyName,
            Industires = data
                .Where(y => y.CompanyId == x.CompanyId)
                .Select(y => new IndustryModel
                {
                    IndustryId = y.IndustryId,
                    IndustryName = y.Industry
                }).ToList()
        })
        .GroupBy(y => y.CompanyId)
        .Select(x => x.First())
        .ToList();
Run Code Online (Sandbox Code Playgroud)

编辑:

另一种不使用“第一”的方法

    var anotherResult = data.GroupBy(x => x.CompanyId)
        .Select(x =>
        {
            var companyModel = new CompanyModel()
            {
                CompanyId = x.Key
            };

            companyModel.Industires = x.Select(y =>
            {
                companyModel.CompanyName = y.CompanyName; // assignign here occurs multiple times however with the same value
                return new IndustryModel
                {
                    IndustryId = y.IndustryId,
                    IndustryName = y.Industry
                };
            }).ToList();

            return companyModel;
        }).ToList();
Run Code Online (Sandbox Code Playgroud)