繁体   English   中英

C# Lambda / 扩展方法使 4 个实体之间的结果变平?

[英]C# Lambda / extension methods flatten results between 4 entities?

我在 EF6 中有一个Tag实体,它与其他 3 个实体具有一对多关系:

              Tag
          /    |      \
Definition   Variant   Machine  

Tag
{
    Id : 1,
    Name : New York,
    Definition
    {
        Id : 1,
        Title: EquipA
    },
    Definition
    {
        Id : 2,
        Title: EquipB
    },
    Variant
    {
        Id : 1,
        Name: EquipA11
    },
    Variant
    {
        Id : 2,
        Name: EquipB11
    },
    Machine
    {
        Id : 1,
        Plant : New York,
        Line : 1A
    }
    Machine
    {
        Id : 2,
        Plant : New York,
        Line : 2B
    }
}

我想返回所有 4 个实体的展平结果,所以我得到这样的结果:

Tag.Id, Tag.Name, Tag.Definition.Id, Tag.Definition.Title, Tag.Variant.Id, Tag.Variant.Name, Tag.Machine.Id, Tag.Machine.Plant, Tag.Machine.Line

1, New York, 1, EquipA, 1, EquipA11, 1, New York, 1A
1, New York, 1, EquipA, 1, EquipA11, 2, New York, 2B
1, New York, 1, EquipA, 2, EquipB11, 1, New York, 1A
1, New York, 1, EquipA, 2, EquipB11, 2, New York, 2B
1, New York, 2, EquipB, 1, EquipA11, 1, New York, 1A
1, New York, 2, EquipB, 1, EquipA11, 2, New York, 2B
1, New York, 2, EquipB, 2, EquipB11, 1, New York, 1A
1, New York, 2, EquipB, 2, EquipB11, 2, New York, 2B  

我能够做到这一点,但我只能得到定义,不知道如何从所有 4 个实体中获取 select:

var temp = db.Tags.Include(c => c.Definition)
              .Include(v => v.Variant)
              .Include(p => p.PaperMachine)
              .SelectMany(t => t.Definition)
              .Select(t => new { t.Id, t.Title } )
              //.SelectMany(c => c.Definition, v => v.Variant,  )
              //.SelectMany(v => v.)
              .ToList();

听起来您想在所有关联实体中生成笛卡尔坐标。

像这样的东西应该可以得到您正在寻找的结果:

var temp = db.Tags
    .SelectMany(t => t.Definitions
        .SelectMany(d => d.Tag.Variants
            .SelectMany(v => v.Tag.PaperMachines
                .Select(p => new 
                {
                   TagId = t.Id, 
                   TagName = t.Name,
                   DefinitionId = d.Id,
                   DefinitionName = d.Name,
                   VariantId = v.Id,
                   VariantName = v.Name,
                   PaperMachineId = p.Id,
                   PaperMachineName = p.Name
                })))).ToList();

这将使用请求的详细信息填充匿名类型。 如果需要 go 回到调用者/视图,您可以定义一个 DTO/ViewModel 来填充和返回。 这需要双向导航属性来从标签到每个子标签并返回标签。 或者,您可以使用Join虽然我怀疑这会有点混乱阅读。

可能有更简洁的方法来获取它。 通常我是在帮助人们避免笛卡尔,而不是故意制造它们。 :)

编辑:对于多对多关系,您可以使用上述查询而不使用反向导航属性...

var temp = db.Tags
    .SelectMany(t => t.Definitions
        .SelectMany(d => t.Variants
            .SelectMany(v => t.PaperMachines
                .Select(p => new 
                {
                   TagId = t.Id, 
                   TagName = t.Name,
                   DefinitionId = d.Id,
                   DefinitionName = d.Name,
                   VariantId = v.Id,
                   VariantName = v.Name,
                   PaperMachineId = p.Id,
                   PaperMachineName = p.Name
                })))).ToList();

这看起来有点奇怪,但似乎确实可以解决问题。 请注意,对于SelectMany连接,我们在t. 参考,但这使我们仍然可以在最终的 Select 中加入我们的 (t)ag、(d)efinition、(v)ariant 和 (p)aperMachine 参考的组合。

请小心,因为随着您引入的组合越多,这将成倍地变得更大和更昂贵。

暂无
暂无

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

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