我有以下 Entity Framework 4.1 实体和关系

Concert ConcertId、AdministratorUserId、名称、IsDeleted

预订
BookingId、ConcertId、UserId、IsDeleted

用户 ID , 用户 ID, 名称, IsDeleted

关系
演唱会 1.....M 预订 1....1 用户

现在我正在尝试为特定的 AdminstratorUserId 选择所有音乐会,但还包括每个音乐会的所有预订以及每个预订的用户详细信息。我还想为每个音乐会、预订和用户应用一个过滤器,其中 IsDeleted == false。我想返回一个音乐会列表,其中的预订和用户详细信息作为导航属性保留。

在 SQL 中,这就是我想要实现的目标:

SELECT *
FROM concert c, booking b, user u
WHERE c.ConcertId = b.ConcertId AND b.UserId = u.UserId AND c.AdministratorId = 10
AND c.IsDeleted = false AND b.IsDeleted = false AND u.IsDeleted = false

据我所知,使用“Include”方法进行急切加载,不允许对其加载的子实体进行过滤或子查询;它返回该连接的所有记录,因此我尝试使用匿名投影,如下所示:
int adminId = 10;

var concerts = _context.Concerts
    .Where(p => p.AdministratorId == adminId && p.IsDeleted == false)
    .Select(p => new {
        Concerts = p,
        Bookings = p.Bookings
            .Where(q => q.IsDeleted == false && q.User.IsDeleted == false)
            .Select(r => new {
                Bookings = r,
                User = r.User
            })
            .AsEnumerable()
            .Select(q => q.Bookings)
    })
    .AsEnumerable()
    .Select(p => p.Concerts)
    .ToList();

但是,这仍然返回所有记录,而不是过滤掉 IsDeleted = true 的记录。任何人都有任何想法或建议,我可以如何清理这个可怕的查询?

我也尝试过类似的方法(http://blogs.msdn.com/b/alexj/archive/2009/06/02/tip-22-how-to-make-include-really-include.aspx) , 再次失败(返回所有预订甚至已删除的预订):
var concertsQuery = (ObjectQuery<Concert>)_context.Concerts
    .Where(p => p.UserId == userId
        && p.IsDeleted == false
        && p.Bookings.Any(q => q.IsDeleted == false && q.User.IsDeleted == false)
    );

var concerts = concertsQuery.Include("Bookings").Include("Bookings.User").ToList();

最佳答案

摆脱那些 AsEnumerable 它们会将您的查询转换为 linq-to-objects:

var concerts = _context.Concerts
    .Where(p => p.AdministratorId == adminId && p.IsDeleted == false)
    .Select(p => new {
        Concerts = p,
        Bookings = p.Bookings
            .Where(q => q.IsDeleted == false && q.User.IsDeleted == false)
            .Select(r => new {
                Bookings = r,
                User = r.User
            })
    })
    .ToList();

关于sql - Entity Framework - 如何过滤预先加载的导航/关系属性?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6452224/

10-11 13:47