2013-03-06 1 views
0

У меня есть объект AllocatedContainers, который имеет внешний ключ для InventoryContainerDetails.EF 5 Связанные с Linq объекты всегда null

Когда я выполняю нижеследующий запрос linq, он возвращает записи, в которых нет связанных записей таблицы в AllocatedContainers, но когда предполагается, что в AllocatedContainer есть объединенная запись, эта целая строка не возвращается. Не могу понять Почему?

Вот класс, обратите внимание на виртуальные отношения к AllocatedContainer

public partial class InventoryContainerDetail 
{ 
    public InventoryContainerDetail() 
    { 
     this.AllocatedContainers = new HashSet<AllocatedContainer>(); 
    } 

    public int Id { get; set; } 
    public int InventoryContainerHeaderId { get; set; } 
    public int ItemId { get; set; } 
    public Nullable<int> ReceiptDetailId { get; set; } 
    public decimal QtyInContainer { get; set; } 


    public virtual InventoryContainerHeader InventoryContainerHeader { get; set; } 
    public virtual Item Item { get; set; } 
    public virtual ICollection<AllocatedContainer> AllocatedContainers { get; set; } 
} 

Вот запрос:

IQueryable<InventoryContainerDetail> containerDtlsToAllocateOLD = 
       repository 
        .SearchFor(
         x => x.InventoryContainerHeader.FacilityId == intFacilityId 
         && x.ItemId == intItemId 
         && (x.QtyInContainer - x.AllocatedContainers.Sum(a => a.AllocatedQty)) > 0 
        ) 
        .OrderBy(x => x.CreatedOn); 

Что тушит этот SQL:

SELECT 
[Project2].[Id1] AS [Id], 
[Project2].[Id] AS [Id1], 
[Project2].[InventoryContainerHeaderId] AS [InventoryContainerHeaderId], 
[Project2].[ItemId] AS [ItemId], 
[Project2].[ReceiptDetailId] AS [ReceiptDetailId], 
[Project2].[QtyInContainer] AS [QtyInContainer], 
[Project2].[CreatedById] AS [CreatedById], 
[Project2].[CreatedOn] AS [CreatedOn], 
[Project2].[ModifiedById] AS [ModifiedById], 
[Project2].[ModifiedOn] AS [ModifiedOn], 
[Project2].[C1] AS [C1], 
[Project2].[Id2] AS [Id2], 
[Project2].[AllocationNeedId] AS [AllocationNeedId], 
[Project2].[AllocatedContainerDetailId] AS [AllocatedContainerDetailId], 
[Project2].[AllocatedQty] AS [AllocatedQty], 
[Project2].[CreatedById1] AS [CreatedById1], 
[Project2].[CreatedOn1] AS [CreatedOn1], 
[Project2].[ModifiedById1] AS [ModifiedById1], 
[Project2].[ModifiedOn1] AS [ModifiedOn1] 
FROM (SELECT 
    [Project1].[Id] AS [Id], 
    [Project1].[InventoryContainerHeaderId] AS [InventoryContainerHeaderId], 
    [Project1].[ItemId] AS [ItemId], 
    [Project1].[ReceiptDetailId] AS [ReceiptDetailId], 
    [Project1].[QtyInContainer] AS [QtyInContainer], 
    [Project1].[CreatedById] AS [CreatedById], 
    [Project1].[CreatedOn] AS [CreatedOn], 
    [Project1].[ModifiedById] AS [ModifiedById], 
    [Project1].[ModifiedOn] AS [ModifiedOn], 
    [Project1].[Id1] AS [Id1], 
    [Extent4].[Id] AS [Id2], 
    [Extent4].[AllocationNeedId] AS [AllocationNeedId], 
    [Extent4].[AllocatedContainerDetailId] AS [AllocatedContainerDetailId], 
    [Extent4].[AllocatedQty] AS [AllocatedQty], 
    [Extent4].[CreatedById] AS [CreatedById1], 
    [Extent4].[CreatedOn] AS [CreatedOn1], 
    [Extent4].[ModifiedById] AS [ModifiedById1], 
    [Extent4].[ModifiedOn] AS [ModifiedOn1], 
    CASE WHEN ([Extent4].[Id] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1] 
    FROM (SELECT 
     [Extent1].[Id] AS [Id], 
     [Extent1].[InventoryContainerHeaderId] AS [InventoryContainerHeaderId], 
     [Extent1].[ItemId] AS [ItemId], 
     [Extent1].[ReceiptDetailId] AS [ReceiptDetailId], 
     [Extent1].[QtyInContainer] AS [QtyInContainer], 
     [Extent1].[CreatedById] AS [CreatedById], 
     [Extent1].[CreatedOn] AS [CreatedOn], 
     [Extent1].[ModifiedById] AS [ModifiedById], 
     [Extent1].[ModifiedOn] AS [ModifiedOn], 
     [Extent2].[Id] AS [Id1], 
     [Extent2].[FacilityId] AS [FacilityId], 
     (SELECT 
      SUM([Extent3].[AllocatedQty]) AS [A1] 
      FROM [dbo].[AllocatedContainers] AS [Extent3] 
      WHERE [Extent1].[Id] = [Extent3].[AllocatedContainerDetailId]) AS [C1] 
     FROM [dbo].[InventoryContainerDetail] AS [Extent1] 
     INNER JOIN [dbo].[InventoryContainerHeader] AS [Extent2] ON [Extent1].[InventoryContainerHeaderId] = [Extent2].[Id]) AS [Project1] 
    LEFT OUTER JOIN [dbo].[AllocatedContainers] AS [Extent4] ON [Project1].[Id] = [Extent4].[AllocatedContainerDetailId] 
    WHERE (([Project1].[QtyInContainer] - [Project1].[C1]) > cast(0 as decimal(18))) AND ([Project1].[FacilityId] = 1) AND ([Project1].[ItemId] = 3027) 
) AS [Project2] 
ORDER BY [Project2].[CreatedOn] ASC, [Project2].[Id1] ASC, [Project2].[Id] ASC, [Project2].[C1] ASC 

Вот является метод репозитория. Обратите внимание, я не буду индуцирования жадную загрузку через .INCLUDE в надежде на его работу, но не повезло:

public override IQueryable<InventoryContainerDetail> SearchFor(Expression<Func<InventoryContainerDetail, bool>> predicate, Expression<Func<InventoryContainerDetail, bool>> orderbylinq = null) 
     { 
      if (orderbylinq == null) 
      { 
       return DbSet.Include("AllocatedContainers").Where(predicate); 
      } 
      else 
      { 
       return DbSet.Include("AllocatedContainers").Where(predicate).OrderBy(orderbylinq); 
      } 
     } 
+0

Что такое код 'DbSet'? –

+0

Можете ли вы использовать 'ToString' вместо' ToList' в запросе для получения сгенерированного SQL и добавить его в свой вопрос? –

+0

Спасибо @LasislavMrnka за то, что посмотрели. Я добавил сгенерированный SQL. –

ответ

0

Хорошо, на самом деле это работает ... Я изменил "&& (x.QtyInContainer - x.AllocatedContainers.Sum(a => a.AllocatedQty)) > 0" к этому "&& (x.QtyInContainer - (x.AllocatedContainers.Count() == 0 ? 0 : x.AllocatedContainers.Sum(a => a.AllocatedQty))) > 0".

Благодаря Ладислав показал мне этот трюк ... вы можете считать, что фактический SQL и вставить его в SQL Server и помочь отладить оттуда тоже, что большой