0

InventoryContainerDetailsへの外部キーを持つエンティティAllocatedContainersがあります。

以下の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

これがリポジトリメソッドです。を介して熱心な読み込みを誘導していることに注意してください。それが機能することを期待して含めますが、運がありません。

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);
            }
        }
4

1 に答える 1

0

わかりました、実際に動作しています...私はこれに変更 "&& (x.QtyInContainer - x.AllocatedContainers.Sum(a => a.AllocatedQty)) > 0" しました "&& (x.QtyInContainer - (x.AllocatedContainers.Count() == 0 ? 0 : x.AllocatedContainers.Sum(a => a.AllocatedQty))) > 0"

そのトリックを見せてくれたLadislavに感謝します...実際のSQLをSQLServerに貼り付けて、そこからデバッグするのを手伝うことができます。これは素晴らしいことです。

于 2013-03-22T20:46:38.930 に答える