Linq查询返回过滤后的数据

时间:2015-02-19 15:48:02

标签: c# linq

我有以下数据结构(事先道歉,因为我不确定在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中)数据并返回数据,但按ProductListTypeIdComponentTypeId过滤

所以例如我有第一个(简单)位

var productListTypeId=1;    
var componentTypeId=4;
var _results=this.Context.GlobalListTable
.Where(i=>i.ProductListTypeId==productListTypeId);

我尝试过添加

.Where(i=>i.ProductGroupTable.ProductTable.ComponentTable.ComponentTypeId == componentTypeId);

但这似乎不起作用。

我想传入(说)上面的参数并返回以下内容:

GlobalListTable1
   ProductGroupTable
       ProductTable1
          ComponentTable4
       ProductTable3   
          ComponentTable4

编辑:使用EntityFramework检索数据

编辑:我开始认为这对于标准的linq查询是不可能的。我似乎能够实现这一目标的唯一方法是遍历查询并手动删除不需要的记录。

2 个答案:

答案 0 :(得分:2)

这就是我最终解决问题的方法。

我不能单独使用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;

如果不是很优雅的话,效果很好。

答案 1 :(得分:1)

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);

修改 如果你需要globalListTable,那么查询将如下所示:

var query =
            global.Where(t => t.ProductListTypeId == productListTypeId).Where(t1=>t1
                .ProductGroupTable
                .ProductTables
                .SelectMany(t => t.ComponentTables)
                .Any(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; }
}