链接到实体框架:只选择子元素的子集

本文关键字:元素 子集 选择 实体 框架 链接 | 更新日期: 2023-09-27 17:50:23

以下设置为真:

  • A是父类
  • B有一对X

  • C有一对X

  • X有一个名为EndDate的属性:这是过滤条件

我想检索一个包含a, B, C和X的集合(A.B.X和A.C.X)我想对集合进行筛选,以便只返回具有X.EndDate = Date的元素。

I 希望X的元素不符合此条件。这可以在一次选择中完成吗?

我正在尝试以下代码:

var set = _context.Set<A>()
    .Include("B.X")
    .Include("C.X")
    .Where(a => a.B.Any(b => b.X.Any(x => x.EndDate == date)) ||
                a.C.Any(c => c.X.Any(x => x.EndDate == date)))
    .ToList();

然而,当B.X在过滤条件内时,它也将包括C.X当B.X (X可以是多个)中的一个符合条件时,它将返回所有B.X实体

我尽力给出一个例子:

A           B           X       X.EndDate
A1          B1          BX1     2015-01-01
A1          B1          BX2     2015-01-02
A1          B2          BX3     2015-01-09
A           C           X       X.EndDate
A1          C1          CX1     2015-01-03
A1          C1          CX2     2015-01-03
A1          C2          CX3     2015-01-02
When date == 2015-01-02
Results are:
A1 B1 BX1
      BX2
   B2 BX3
   C1 CX1
      CX2
   C2 CX3 
Desired results are:
A1 B1 BX2
   C2 CX2

注意:我只能使用这种表示法,而不能使用类似sql的表示法。还有更多的实体需要包含,这可以(显然)只能通过。include(")加引号

链接到实体框架:只选择子元素的子集

来完成。

你要做的是过滤包含的表,这不是实体框架现在支持的东西:http://entityframework.codeplex.com/workitem/47。如果你正在处理简单的类,那么你可以在你的select语句中实例化新的A,像这样:

var set = _context.Set<A>()
    .Include("B.X")
    .Include("C.X")
    .Where(a => a.B.Any(b => b.X.Any(x => x.EndDate == date)) ||
                a.C.Any(c => c.X.Any(x => x.EndDate == date)))
    .Select(a => new A() 
    {
        B = a.B
            .Where(b => b.X.Any(x => x.EndDate == DatePicker))
            .Select(b => new B()
                {
                    X = b.X.Where(x => x.EndDate == DatePicker) 
                }),
        C = a.C
            .Where(c => c.X.Any(x => x.EndDate == DatePicker))
            .Select(c => new C()
                {
                    X = c.X.Where(x => x.EndDate == DatePicker) 
                })
    });

如果你的类不是那么简单,也就是说,你有很多属性,你必须在你的选择语句中映射,或者你有复杂的业务验证规则,那么你最好的选择可能是继续你的查询,并在使用它之前简单地从结果集中删除你不想要的B, C和X。

像这样?

from a in _context.Set<A>()
from b in a.B
from c in a.C
let bx = b.X.Where( x => x.EndDate == date )
let cx = c.X.Where( x => x.EndDate == date )
where bx.Any() || cx.Any()
select { a, b, c, bx, cx };

请注意,您可能会在结果集中得到重复的ab和/或c


如果您不能使用LINQ语法,那么这段代码通常(虽然有点难看)会转换为扩展方法调用:

_context.Set<A>()
.SelectMany( a => a.B, (a, b) => new { a, b, bx = b.X.Where( ... ) } )
.SelectMany( x => x.a.C, (x, c) => new { x.a, x.b, x.bx, c, cx = c.X.Where( ... ) } )
.Where( x => x.bx.Any() || x.cx.Any() )