条件IQueryable选择(MVC .NET EF)

时间:2013-06-13 23:19:48

标签: c# asp.net-mvc entity-framework select

我正在尝试在加载一些数据时选择多个子项,但我想在包含的内部放置条件语句。

目前我在不同的方法中有很多不同的选择,使用1个特定的祖父对象,但是想把它们放在一个选择中

ShapeResults(this IQueryable<SpecificObject>, bool includeParent, bool includeChildren)

方法和我的所有方法都指向条件/过滤器。

我正在做的事情很棒:

var query = context.Grandparent.Select(i => new GrandparentObject
{
    GrandparentProp1 = i.GrandparentProp1 ,
    Parents = i.Parents.Select(j => new ParentObject
    {
        ParentProp1 = j.ParentProp1,
        Children = j.Children.Select(k => new ChildObject
        {
            ChildProp1 = k.ChildProp1,
        }
    }
}

我本质上喜欢做什么

var query = context.Grandparent.Select(i => new GrandparentObject
{
    GrandparentProp1 = i.GrandparentProp1,
--> if (IncludeParents)
    Parents = i.Parents.Select(j => new ParentObject
    {
        ParentProp1 = j.ParentProp1,
    --> if (IncludeParentsChildren)
        Children = j.Children.Select(k => new ChildObject
        {
            ChildProp1 = k.ChildProp1,
        }
    }
}

提前致谢!

2 个答案:

答案 0 :(得分:1)

如何像这样使用the conditional operator

var query = context.Grandparent.Select(i => new GrandparentObject
{
    GrandparentProp1 = i.GrandparentProp1,
    Parents = includeParents
        ? i.Parents.Select(j => new ParentObject
          {
              ParentProp1 = j.ParentProp1,
              Children = includeChildren
                  ? j.Children.Select(k => new ChildObject
                    {
                         ChildProp1 = k.ChildProp1
                    }
                  : Enumerable.Empty<Child>()
          }
        : Enumerable.Empty<Parent>()
};

您也可以使用null代替Enumerable.Empty<TResult>(),具体取决于您希望返回结果的语义。


编辑:刚刚意识到我完全无法理解这需要多么复杂。试试这样:

var query = context.Grandparent.Select(i => new GrandparentObject
{
    GrandparentProp1 = i.GrandparentProp1 ,
    Parents = i.Parents
        .Where(_ => includeParents)
        .Select(j => new ParentObject
    {
        ParentProp1 = j.ParentProp1,
        Children = j.Children
            .Where(_ => includeChildren)
            .Select(k => new ChildObject
        {
            ChildProp1 = k.ChildProp1,
        }
    }
}

答案 1 :(得分:0)

亚当 我一直在做类似的事情,并建议这样的事情:

var query = context.Grandparent
                   .Select(poco => new 
                    {
                        poco     = poco,
                        parents  = poco.Parents.Where(x => includeParents)
                        children = poco.Children.Where(x => includeChildren) 
                    })
                   .Select(x => new GrandparentObject
{
    GrandparentProp1 = x.poco.GrandparentProp1,
    Parents          = x.parents.Select(parent => new ParentObject
                       {
                           ParentProp1 = parent .ParentProp1,
                           Children    = x.children.Select(child => new ChildObject
                                         {
                                             ChildProp1 = child.ChildProp1,
                                         }
                       }
}

我发现使用Ternary operator证明很难。 对条件连接使用附加的select语句似乎是最好的方法。

重要说明: .Where(x => includeChildren) vs .Where(x => false)将生成不同的SQL查询。

如果使用变量(includeChildren),EF仍然会执行一个不返回任何内容的连接,但如果使用常量(false),它将完全跳过连接。