【问题标题】:Linq multi level inner joinLinq 多级内连接
【发布时间】:2016-04-12 07:06:12
【问题描述】:

我有 3 个不同的实体:

E1, E2, E3

E1 有一个属性是 E2 的 ObservableCollection。 E2 有一个属性是 E3 的 ObservableCollection。

通过 linq 查询,我想以我得到的 E1 作为起点来获取所有 E3。

我试过类似的东西:

Query = Query.Where<E3>(i => E1.E2List.Select(ep => ep.E3List.Select(ai => ai.id))
             .Contains(i.id));

基本意思:从 E1 获取 E2 列表中 E3 列表中所有 E3 的 id 列表

但正如你猜想的那样,这是行不通的。

My starting point is this :
//make the array 
E3[] array;
//get all E3 datas
IQueryable<E3> Query = DBSetE3.AsQueryable();

而且我的数组中必须有所有结果

所以我的结果应该是:进入数组,所有链接到 E2 的 E3 对象都包含在 E1 中,基于 E1。

例如:

Entity 1| List of E2
E1 | E2A, E2B

Entity 2 | List of E3
E2B | E3C, E3D
E2A | E3E, E3F

当我搜索链接到 E1 的 E3 时,我必须得到 E3C、E3D、E3E、E3F

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    你可以这样做:

    var e1Ids = new [] { 1, 2, 3 };
    var e3s = DBSetE1.AsQueryable().Where(e => e1Ids.Contains(e.Id))
                                   .SelectMany(e => e.E2List)
                                   .SelectMany(e => e.E3List);
    

    基本上,您可以根据输入过滤所有 E1。然后你想SelectMany(将结果[[1,2],[3,4]] 扁平化为[1,2,3,4])来获取E2。然后你 SelectMany 是 E3s。

    【讨论】:

    • 这很好用,除非我从 E1 中删除了一个对象并重新计算而不对我的数据上下文执行 SaveChanges。最奇怪的是(根据我的测试数据):我从 E1 中删除 E2A,然后计算。当我检查 E1 时,只有 E2B(如预期的那样),但.SelectMany(e =&gt; e.E2List) 带来了E3C, E3D, E3E, E3F,而它应该只得到E3E, E3F。如果我自动保存它可以完美运行,但是自动保存不太好。有什么想法可以完成答案(不过,我认为您的答案已被接受,因为它工作正常)?
    • @Zaphod 在这种情况下,您需要在内存中运行查询,而不是再次访问数据库。我的意思是你会写e3s.Where(而不是DBSetE1.AsQueryable().Where(。这样,它将在内存中进行评估,而不是读取数据库中的陈旧数据。那当然是假设e3s 已经实现(即不是IQueryable&lt;&gt;,而应该是IList&lt;&gt;IEnumerable&lt;&gt; 等)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-06
    • 1970-01-01
    • 1970-01-01
    • 2019-01-29
    • 1970-01-01
    相关资源
    最近更新 更多