2011-06-23 42 views
3

我有以下的實體框架4.1的實體和關係實體框架 - 如何過濾預先加載的導航/關係屬性?

音樂會 ConcertId,AdministratorUserId,名稱,請將isDeleted

預訂 BookingId,ConcertId,用戶ID,請將isDeleted

用戶ID,用戶ID ,Name,IsDeleted

Relat ionships 音樂會1 .....中號的預訂1 .... 1用戶

現在我想選擇一個特定的AdminstratorUserId所有的音樂會也包括每個音樂會所有的預訂,也是用戶的詳細信息爲每個預訂。我還想爲每個Concert,Booking和用戶應用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 

據我所知,採用「包含」方法急於負載,不允許孩子的濾波或子查詢它加載的實體;它返回該加入所有記錄,所以我嘗試如下使用匿名投影:

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哪裏=真。任何人有任何想法,或建議如何我可以清理這個怪異的查詢?

我也試過類似這樣的方法(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(); 

回答

0

所以,我設法解決這個問題的方法是按照Ladislav的回答運行LINQ查詢,然後使用匿名對象重新連接個人如下idual對象到其正確的關係屬性:

var concertResult = new List<Concert>(); 

foreach (var concertObject in concerts) 
{ 
    var concert = concertObject.Concert; 

    foreach (var bookingObject in concertObject.Bookings) 
    { 
     var booking = bookingObject.Booking; 
     booking.User = bookingObject.User; 
     concert.Bookings.Add(booking); 
    } 
    concertResult.Add(concert); 
} 
1

擺脫那些AsEnumerable,他們會變成你的查詢LINQ到對象:

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(); 
+0

不幸的是我需要返回一個列表,這似乎回到了新的匿名類型的列表。有沒有方法可以返回導航屬性仍然​​完好無損的音樂會列表? – romiem

+0

如果您想要訂購相關實體,則無法返回音樂會列表。執行此查詢後,您可以嘗試將匿名結構轉換爲音樂會。 –