通用存储库:如何在同一个类上连接列表属性

时间:2015-09-24 18:06:23

标签: c# linq

我有一个具有两个列表属性的类,需要由该类的使用者加入。通过通用存储库检索该类。这是方法:

IList<TEntity> GetAll(params Expression<Func<TEntity, object>>[] navigationProperties);

具有子类/列表属性的类:

public class A
{
    // I need to join these 2 in the caller
    public IList<B> BList { get; set; } // Bs have an ID property
    public IList<C> CList { get; set; } // Cs have an ID property
}

使用(这是我尝试过的):

var x = Repository.GetAll(i=>i.BList)
        .Join(Repository.GetAll(i=>i.CList), outerkey => outerkey.???, ...

Intellisense仅显示A类的属性,而不是B或C.为什么不显示B和C的ID属性?我接近这个错吗?这不是一个智力问题。

2 个答案:

答案 0 :(得分:1)

当前设置中的

GetAll会返回A的列表,我假设已填充相关的B。然后,您尝试将 加入另一个A的{​​{1}}列表,并填充C

我想要的 是一个A个列表,其中 bc已填充,然后在加入BC s后进行一些投影。

我会逐步完成,首先使用SelectMany展平已加入的BC的列表,然后投射到单个匿名类型

(请注意,我正在使用Join部分的查询语法,因为在这种情况下它比方法语法更清晰)

//`A`s with `B`s and `C`s populated
var as = Repository.GetAll(i=>i.BList, i=>i.CList);

var query = as.SelectMany(a => (from b in a.BList
                                join c in a.CList
                                   on b.Id equals c.Id
                                select new {b, c}),   // get the matching Bs and Cs
                         (a, bc) => a./*A Property here*/,
                                    bc.b./*B property here*/,                                                    
                                    bc.c./*C property here*/)
                         )

答案 1 :(得分:0)

Intellisense有时难以跟上代码编辑器 - 我在使用LINQ的Visual Studio 2013中看到了很多。您可以做的一件事是elide类型推断,并在join方法中指定泛型类型参数。这不是确切的,但是像这样:

...Join<B, C, int, B>(outer => outer.ID, inner => inner.ID, <etc etc>

前两个类型参数分别是外部和内部列表的类型(在您的情况下,B和C)。第三个是密钥的类型(即ID)。最后一个是结果的类型。如果你想使用匿名类型,那么你不得不使用类型推断。