C# 返回过滤数据的Linq查询

C# 返回过滤数据的Linq查询,c#,linq,C#,Linq,我有以下数据结构(请提前道歉,因为我不确定在SO中表示数据结构的最佳方式)。 以下是链接的表列表(由一对多表示) 1 | 8 关系 --------------------- |GlobalListTable: | |-------------------| |Id | |ProductGroupTableId| |ProductListTypeId | --------------------- 8 |

我有以下数据结构(请提前道歉,因为我不确定在SO中表示数据结构的最佳方式)。 以下是链接的表列表(由一对多表示)

1
|
8
关系

---------------------
|GlobalListTable:   |
|-------------------|
|Id                 |
|ProductGroupTableId|
|ProductListTypeId  |   
---------------------
         8
         |
         1
---------------------
|ProductGroupTable: |
|-------------------|
|Id                 |
|Name               |
---------------------
         1
         |
         8
---------------------
|ProductTable:      |
|-------------------|
|Id                 |
|Name               |
|ProductGroupTableId|
---------------------
         1
         |
         8
---------------------
|ComponentTable:    |
|-------------------|
|Id                 |
|Name               |
|ProductTableId     |
|ComponentTypeId    |
---------------------
最简单形式的数据如下所示

GlobalListTable1
   ProductGroupTable
       ProductTable1
          ComponentTable ComponentTypeId1
          ComponentTable ComponentTypeId2
          ComponentTable ComponentTypeId3
          ComponentTable ComponentTypeId4
        ProductTable2
          ComponentTable ComponentTypeId1
          ComponentTable ComponentTypeId3
       ProductTable3   
          ComponentTable ComponentTypeId3
          ComponentTable ComponentTypeId4
我想做的是查询(在lambda中)数据并返回数据,但通过
ProductListTypeId
ComponentTypeId

举个例子,我有一个简单的例子

我试着添加

.Where(i=>i.ProductGroupTable.ProductTable.ComponentTable.ComponentTypeId == componentTypeId);
但这似乎不起作用

我想传入(比如)上述参数并返回以下内容:

GlobalListTable1
   ProductGroupTable
       ProductTable1
          ComponentTable4
       ProductTable3   
          ComponentTable4
编辑:使用EntityFramework检索数据


编辑:我开始认为这在标准linq查询中是不可能的。我似乎能够使这项工作正常进行的唯一方法是迭代查询并手动删除不需要的记录。

SelectMany将完成这项工作,以下是查询:

var global = new List<GlobalListTable>()
        {
            new GlobalListTable()
            {
                ProductListTypeId = 1,
                ProductGroupTable = new ProductGroupTable()
                {
                    ProductTables = new List<ProductTable>()
                    {
                        new ProductTable()
                        {
                            ComponentTables = new List<ComponentTable>()
                            {
                                new ComponentTable(){ComponentTypeId = 4, Name = "Sucess"}
                            }
                        }
                    }
                }
            }
        };

        var productListTypeId=1;    
        var componentTypeId=4;
        var query =
            global.Where(t => t.ProductListTypeId == productListTypeId)
                .Select(t => t.ProductGroupTable)
                .SelectMany(t => t.ProductTables)
                .SelectMany(t => t.ComponentTables)
                .Where(t => t.ComponentTypeId == componentTypeId);
EDIT2

var filterComp =
                global.Select(t => t.ProductGroupTable)
                    .SelectMany(t => t.ProductTables)
                    .SelectMany(t => t.ComponentTables)
                    .Where(t => t.ComponentTypeId == componentTypeId);
我使用了定义如下的poco类:

internal class GlobalListTable
{
    public ProductGroupTable ProductGroupTable { get; set; }
    public int ProductListTypeId { get; set; }
}

internal class ProductGroupTable
{
    public List<ProductTable> ProductTables { get; set; }
}

internal class ProductTable
{
    public List<ComponentTable> ComponentTables { get; set; }
}

internal class ComponentTable
{
    public string Name { get; set; }
    public int ComponentTypeId { get; set; }
}
内部类globallistable
{
public ProductGroupTable ProductGroupTable{get;set;}
public int ProductListTypeId{get;set;}
}
内部类ProductGroupTable
{
公共列表ProductTables{get;set;}
}
内部类ProductTable
{
公共列表组件表{get;set;}
}
内部类组件表
{
公共字符串名称{get;set;}
public int ComponentTypeId{get;set;}
}

这就是我最终解决问题的原因

看起来我无法单独使用linq实现它,所以我需要迭代结果并消除不需要的结果

获取顶级对象的查询:

var query = this.Context.GlobalListTable
        .Where(i => i.ProductListTypeId == productListTypeId)
        .Select(i => i.ProductGroupTable)
        .SelectMany(i => i.ComponentTables)
        .Where(t => t.ComponentTypeId == componentTypeId)           
        .ToList();
迭代结果并排除不需要的内容:

foreach (var _globalListTable in query)
{
    foreach (var _productTable in _globalListTable.ProductGroupTable.ProductTables)
    {
        var _exclude = _productTable.ComponentTables.Where(i => i.ComponentTypeId != componentTypeId);
        _productTable.ComponentTables = _productTable.ComponentTables.Except(_exclude).ToList();
    }
}

return query;

即使不优雅,也能完美地工作。

您使用的是EntityFramework吗?会出现什么错误/什么是“不工作”行为?@Bob-正确版本6@StevenWexler-语法不起作用。我是如何写的,这是我在脑海中想象的,但语法不正确。我试过了,但它只返回一个IEnumerable。我希望IEnumerable像示例一样填充它-只有符合条件的子记录。@DeclanMcD抱歉,我误解了你,edited我的回答是关闭的,但它仍然不起作用。它以正确的格式返回数据,但没有过滤。即,它仍然返回ComponentTable中的所有记录,而不是谓词过滤器(t.ComponentTypeId==ComponentTypeId)。我目前的做法是迭代列表并手动删除所有不匹配的记录-非常乏味。奇怪的是,这些评论似乎不接受我以前评论中的文本@Alex Voskresenskiy?@DeclanMcD,是的,我的错。有关筛选器,请参阅Edit2。当然,执行两个单独的查询并不好,但我无法删除o更好。不要忘记在第一个查询中使用ToList,这样EF就不会在dbsometime中进行更多的查询,我只是不会首先使用EF,有时它只能在存储过程和SQL中进行。
var query = this.Context.GlobalListTable
        .Where(i => i.ProductListTypeId == productListTypeId)
        .Select(i => i.ProductGroupTable)
        .SelectMany(i => i.ComponentTables)
        .Where(t => t.ComponentTypeId == componentTypeId)           
        .ToList();
foreach (var _globalListTable in query)
{
    foreach (var _productTable in _globalListTable.ProductGroupTable.ProductTables)
    {
        var _exclude = _productTable.ComponentTables.Where(i => i.ComponentTypeId != componentTypeId);
        _productTable.ComponentTables = _productTable.ComponentTables.Except(_exclude).ToList();
    }
}

return query;