Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
LINQ到实体框架-多个包含路径导致糟糕的TSQL_Tsql_Entity Framework_Entity Framework 4_Linq To Entities - Fatal编程技术网

LINQ到实体框架-多个包含路径导致糟糕的TSQL

LINQ到实体框架-多个包含路径导致糟糕的TSQL,tsql,entity-framework,entity-framework-4,linq-to-entities,Tsql,Entity Framework,Entity Framework 4,Linq To Entities,给定以下LINQ到实体(EF4)查询 在哪里 文档总是有一个批,而批又总是有一个 财政期间和承包者 文档将始终具有一个或多个 更多GroupTypeHistory,每个都将始终有一个GroupType 一个文档将有零个或多个项,而这些项又将有一个 或更多版本的 一个版本将有零个或一个ProductPackPeriodic ProductPackPeriodic始终有一个ProductPack和一个ProductPack ProductPeriodic,以及零个或一个特殊容器指示器 Produc

给定以下LINQ到实体(EF4)查询

在哪里

  • 文档总是有一个批,而批又总是有一个 财政期间和承包者
  • 文档将始终具有一个或多个 更多GroupTypeHistory,每个都将始终有一个GroupType
  • 一个文档将有零个或多个项,而这些项又将有一个 或更多版本的
  • 一个版本将有零个或一个ProductPackPeriodic
  • ProductPackPeriodic始终有一个ProductPack和一个ProductPack ProductPeriodic,以及零个或一个特殊容器指示器
  • ProductPack始终有一个产品
  • 一个产品将有零个或一个制造商,零个或一个送货上门
  • 一个版本将有零个或多个背书,每个背书将有一个周期性签名
上面的LINQ查询生成了我所见过的一些最差的TSQL,其中一些相关表被多次包含(可能是因为它们在查询中被多次引用),并且所需时间比我希望运行的要长得多(相关表可能包含数百万行,但这不是原因)

我知道必须有更好的方法来编写它(考虑到我上面描述的所有不同引用类型),这将产生更好的TSQL,但是我尝试的每个版本都无法正确返回数据

有人能帮我找到更好的解决办法吗

如果这使它更容易理解,如果我直接编写TSQL,我将看到如下内容

select *
from Document d
    inner join Batch b 
        inner join FinancialPeriod fp on b.FinancialPeriodID = fp.FinancialPeriodID
        inner join Contractor c on b.ContractorID = c.ContractorID
    on d.BatchID = b.BatchID
    inner join DocumentGroupType dgt on d.DocumentID = dgt.DocumentID
    left join Item i
        left join ItemVersion iv
            left join ProductPackPeriodic ppp
                inner join ProductPack pack 
                    inner join Product p 
                        left join Manufacturer m on p.ManufacturerID = m.ManufacturerID
                        left join HomeDeliveryProduct hdp on p.ProductID = hdp.ProductID
                    on pack.ProductID = p.ProductID
                on ppp.ProductPackID = pack.ProductPackID
                inner join ProductPeriodic pp on ppp.ProductPeriodicID = pp.ProductPeriodicID
                left join SpecialContainerIndicator sci on ppp.SpecialContainerIndicatorCode = sci.SpecialContainerIndicatorCode
            on iv.ProductPackPeriodicID = ppp.ProductPackPeriodicID
            left join ItemVersionEndorsement ive 
                inner join EndorsementPeriodic ep on ive.EndorsementPeriodicID = ep.EndorsementPeriodicID
            on iv.ItemVersionID = ive.ItemVersionID
        on i.ItemID = iv.ItemID
    on d.DocumentID = i.DocumentID
where d.DocumentID = 33 -- example value
这也可以使关系要求更清晰


提前谢谢。

对于EF,我没有什么好的答案,但它可能适合您使用micro ORM进行某些复杂的查询。Micro-ORMs本质上是SQL上的低级包装器,它允许您获取强类型对象以及其他方便的特性。例如,您可以看一看,这个站点使用它来进行一些瓶颈查询。它的性能应该非常接近本机SQL性能。

对于这种情况,我编写了特定的存储过程,然后使用带有自定义物化器的EFExtensions,不仅可以获得优异的性能,而且可以正确地物化实体。

回答得非常好;正如我所希望的那样,这大大提高了性能,并且(正如您所建议的)允许我指定自己的TSQL。谢谢
select *
from Document d
    inner join Batch b 
        inner join FinancialPeriod fp on b.FinancialPeriodID = fp.FinancialPeriodID
        inner join Contractor c on b.ContractorID = c.ContractorID
    on d.BatchID = b.BatchID
    inner join DocumentGroupType dgt on d.DocumentID = dgt.DocumentID
    left join Item i
        left join ItemVersion iv
            left join ProductPackPeriodic ppp
                inner join ProductPack pack 
                    inner join Product p 
                        left join Manufacturer m on p.ManufacturerID = m.ManufacturerID
                        left join HomeDeliveryProduct hdp on p.ProductID = hdp.ProductID
                    on pack.ProductID = p.ProductID
                on ppp.ProductPackID = pack.ProductPackID
                inner join ProductPeriodic pp on ppp.ProductPeriodicID = pp.ProductPeriodicID
                left join SpecialContainerIndicator sci on ppp.SpecialContainerIndicatorCode = sci.SpecialContainerIndicatorCode
            on iv.ProductPackPeriodicID = ppp.ProductPackPeriodicID
            left join ItemVersionEndorsement ive 
                inner join EndorsementPeriodic ep on ive.EndorsementPeriodicID = ep.EndorsementPeriodicID
            on iv.ItemVersionID = ive.ItemVersionID
        on i.ItemID = iv.ItemID
    on d.DocumentID = i.DocumentID
where d.DocumentID = 33 -- example value