以下设置为真:
- A是父类
- A有一对多B
A有一到多个C
B有一到多个X
C有一到多个X
X有一个名为EndDate的属性:这是过滤条件
我想要检索一个包含A,B,C和X的集合(A.B.X和A.C.X)
我想过滤该集合,只返回具有X.EndDate = Date
。
我不希望X的元素不通过此条件。 这可以在一个Select中完成吗?
我正在尝试关注代码:
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(“”)来完成
答案 0 :(得分:3)
您要做的是过滤所包含的表,而这不是Entity Framework现在支持的内容: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)
})
});
如果您的课程不那么简单,即您必须在select语句中映射许多属性,或者您有复杂的业务验证规则,那么您最好的选择可能是继续查询,只需删除在使用它之前,你不想从你的结果集中得到B,C和X.
答案 1 :(得分:1)
这样的东西?
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 };
请注意,您可能会在结果集中重复a
,b
和/或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() )