如何创建 T-SQL 与 Entity Framework 核心交叉应用?
How do I create a T-SQL Cross-Apply with Entity Framework Core?
我想用 Entity Framework Core 创建一个查询,它有多个 INNER JOIN 和一个 CROSS APPLY。
我可以很好地创建 INNER JOIN,但似乎无法使 CROSS APPLY 工作。
- 做了一些 Google 搜索总线没有真正有用的结果
- 用 Entity Framework linq 语句尝试了不同的方法,但到目前为止无济于事。
这是我目前得到的 EF 查询:
comCommunicationContext
.Communication
.AsNoTracking()
.Where(c => c.Label.InternalName == labelName &&
c.Businesstransaction.DocumentType.DocumentTypeName == documentType &&
c.Businesstransaction.SourceSystem.SourceSystemName == sourceSystem)
.Join(comCommunicationContext.CommunicationOutputChannel, communicationEntity => communicationEntity.CommunicationId, communicationOutputChannelEntity => communicationOutputChannelEntity.CommunicationId, (communicationEntity, communicationOutputChannelEntity) => new {Communication = communicationEntity, CommunicationOutputChannel = communicationOutputChannelEntity})
.Where(y => y.CommunicationOutputChannel.OutputChannel == outputChannel)
.Join(comCommunicationContext.CommunicationStatusOutputChannel.
Where(x => x.Status=="to process"), communicationOutputChannelEntity => communicationOutputChannelEntity.CommunicationOutputChannel.CommunicationOutputChannelId, communicationStatusOutputChannelEntity => communicationStatusOutputChannelEntity.CommunicationOutputChannelId, (outer, inner) => new Communication() { CommunicationDataEnriched = outer.Communication.CommunicationDataEnriched })
产生以下 T-SQL 查询:
SELECT [c].[CommunicationDataEnriched]
FROM [Communications] AS [c]
INNER JOIN [Businesstransactions] AS [c.Businesstransaction] ON [c].[BusinessTransactionId] = [c.Businesstransaction].[BusinessTransactionId]
INNER JOIN [DocumentTypes] AS [c.Businesstransaction.DocumentType] ON [c.Businesstransaction].[DocumentTypeId] = [c.Businesstransaction.DocumentType].[DocumentTypeId]
INNER JOIN [SourceSystems] AS [c.Businesstransaction.SourceSystem] ON [c.Businesstransaction].[SourceSystemId] = [c.Businesstransaction.SourceSystem].[SourceSystemId]
INNER JOIN [Labels] AS [c.Label] ON [c].[LabelId] = [c.Label].[LabelId]
INNER JOIN [CommunicationOutputChannels] AS [CommunicationOutputChannels] ON [c].[CommunicationId] = [CommunicationOutputChannels].[CommunicationId]
INNER JOIN (
SELECT [x].*
FROM [CommunicationStatusOutputChannels] AS [x]
WHERE [x].[Status] = 'to process'
) AS [t] ON [CommunicationOutputChannels].[CommunicationOutputChannelId] = [t].[CommunicationOutputChannelId]
WHERE ((([c.Label].[InternalName] = 'labelname') AND ([c.Businesstransaction.DocumentType].[DocumentTypeName] = 'documenttype')) AND ([c.Businesstransaction.SourceSystem].[SourceSystemName] = 'sourcessysem')) AND ([CommunicationOutputChannels].[OutputChannel] = 'email')
我想发送到数据库的是:
SELECT [c].[CommunicationDataEnriched]
FROM [Communications] AS [c]
INNER JOIN [Businesstransactions] AS [c.Businesstransaction] ON [c].[BusinessTransactionId] = [c.Businesstransaction].[BusinessTransactionId]
INNER JOIN [DocumentTypes] AS [c.Businesstransaction.DocumentType] ON [c.Businesstransaction].[DocumentTypeId] = [c.Businesstransaction.DocumentType].[DocumentTypeId]
INNER JOIN [SourceSystems] AS [c.Businesstransaction.SourceSystem] ON [c.Businesstransaction].[SourceSystemId] = [c.Businesstransaction.SourceSystem].[SourceSystemId]
INNER JOIN [Labels] AS [c.Label] ON [c].[LabelId] = [c.Label].[LabelId]
INNER JOIN [CommunicationOutputChannels] AS [CommunicationOutputChannels] ON [c].[CommunicationId] = [CommunicationOutputChannels].[CommunicationId]
CROSS APPLY (
SELECT TOP 1 [x].*
FROM [CommunicationStatusOutputChannels] AS [x]
WHERE [x].[Status] = 'to process'
AND [x].[CommunicationOutputChannelId] = [CommunicationOutputChannels].[CommunicationOutputChannelId]
ORDER BY [x].createdOn DESC
) [t]
WHERE ((([c.Label].[InternalName] = 'labelname') AND ([c.Businesstransaction.DocumentType].[DocumentTypeName] = 'documenttype')) AND ([c.Businesstransaction.SourceSystem].[SourceSystemName] = 'sourcessysem')) AND ([CommunicationOutputChannels].[OutputChannel] = 'email')
对象 CommunicationOutputChannel
具有 ICollection<CommunicationStatusOutputChannel>
类型的导航 属性 CommunicationStatusOutputChannels
(CommunicationOutputChannel
和 CommunicationStatusOutputChannels
个实体)。
所以表 CommunicationOutputChannels
和 CommunicationStatusOutputChannels
之间的最后一个 INNER JOIN
应该是 CROSS APPLY
.
没关系。找到适合我的解决方案。
var q = from c in comCommunicationContext.Communication.Where(c=>c.Label.InternalName==labelName && c.Businesstransaction.DocumentType.DocumentTypeName==documentType && c.Businesstransaction.SourceSystem.SourceSystemName==sourceSystem)
join coc in comCommunicationContext.CommunicationOutputChannel
on c.CommunicationId equals coc.CommunicationId
from csoc in comCommunicationContext.CommunicationStatusOutputChannel.Where(x=>x.CommunicationOutputChannelId==coc.CommunicationOutputChannelId).OrderByDescending(y=>y.CreatedOn).Take(1)
where csoc.Status == "to process"
select new Communication(){CommunicationDataEnriched = c.CommunicationDataEnriched}
;
我想用 Entity Framework Core 创建一个查询,它有多个 INNER JOIN 和一个 CROSS APPLY。
我可以很好地创建 INNER JOIN,但似乎无法使 CROSS APPLY 工作。
- 做了一些 Google 搜索总线没有真正有用的结果
- 用 Entity Framework linq 语句尝试了不同的方法,但到目前为止无济于事。
这是我目前得到的 EF 查询:
comCommunicationContext
.Communication
.AsNoTracking()
.Where(c => c.Label.InternalName == labelName &&
c.Businesstransaction.DocumentType.DocumentTypeName == documentType &&
c.Businesstransaction.SourceSystem.SourceSystemName == sourceSystem)
.Join(comCommunicationContext.CommunicationOutputChannel, communicationEntity => communicationEntity.CommunicationId, communicationOutputChannelEntity => communicationOutputChannelEntity.CommunicationId, (communicationEntity, communicationOutputChannelEntity) => new {Communication = communicationEntity, CommunicationOutputChannel = communicationOutputChannelEntity})
.Where(y => y.CommunicationOutputChannel.OutputChannel == outputChannel)
.Join(comCommunicationContext.CommunicationStatusOutputChannel.
Where(x => x.Status=="to process"), communicationOutputChannelEntity => communicationOutputChannelEntity.CommunicationOutputChannel.CommunicationOutputChannelId, communicationStatusOutputChannelEntity => communicationStatusOutputChannelEntity.CommunicationOutputChannelId, (outer, inner) => new Communication() { CommunicationDataEnriched = outer.Communication.CommunicationDataEnriched })
产生以下 T-SQL 查询:
SELECT [c].[CommunicationDataEnriched]
FROM [Communications] AS [c]
INNER JOIN [Businesstransactions] AS [c.Businesstransaction] ON [c].[BusinessTransactionId] = [c.Businesstransaction].[BusinessTransactionId]
INNER JOIN [DocumentTypes] AS [c.Businesstransaction.DocumentType] ON [c.Businesstransaction].[DocumentTypeId] = [c.Businesstransaction.DocumentType].[DocumentTypeId]
INNER JOIN [SourceSystems] AS [c.Businesstransaction.SourceSystem] ON [c.Businesstransaction].[SourceSystemId] = [c.Businesstransaction.SourceSystem].[SourceSystemId]
INNER JOIN [Labels] AS [c.Label] ON [c].[LabelId] = [c.Label].[LabelId]
INNER JOIN [CommunicationOutputChannels] AS [CommunicationOutputChannels] ON [c].[CommunicationId] = [CommunicationOutputChannels].[CommunicationId]
INNER JOIN (
SELECT [x].*
FROM [CommunicationStatusOutputChannels] AS [x]
WHERE [x].[Status] = 'to process'
) AS [t] ON [CommunicationOutputChannels].[CommunicationOutputChannelId] = [t].[CommunicationOutputChannelId]
WHERE ((([c.Label].[InternalName] = 'labelname') AND ([c.Businesstransaction.DocumentType].[DocumentTypeName] = 'documenttype')) AND ([c.Businesstransaction.SourceSystem].[SourceSystemName] = 'sourcessysem')) AND ([CommunicationOutputChannels].[OutputChannel] = 'email')
我想发送到数据库的是:
SELECT [c].[CommunicationDataEnriched]
FROM [Communications] AS [c]
INNER JOIN [Businesstransactions] AS [c.Businesstransaction] ON [c].[BusinessTransactionId] = [c.Businesstransaction].[BusinessTransactionId]
INNER JOIN [DocumentTypes] AS [c.Businesstransaction.DocumentType] ON [c.Businesstransaction].[DocumentTypeId] = [c.Businesstransaction.DocumentType].[DocumentTypeId]
INNER JOIN [SourceSystems] AS [c.Businesstransaction.SourceSystem] ON [c.Businesstransaction].[SourceSystemId] = [c.Businesstransaction.SourceSystem].[SourceSystemId]
INNER JOIN [Labels] AS [c.Label] ON [c].[LabelId] = [c.Label].[LabelId]
INNER JOIN [CommunicationOutputChannels] AS [CommunicationOutputChannels] ON [c].[CommunicationId] = [CommunicationOutputChannels].[CommunicationId]
CROSS APPLY (
SELECT TOP 1 [x].*
FROM [CommunicationStatusOutputChannels] AS [x]
WHERE [x].[Status] = 'to process'
AND [x].[CommunicationOutputChannelId] = [CommunicationOutputChannels].[CommunicationOutputChannelId]
ORDER BY [x].createdOn DESC
) [t]
WHERE ((([c.Label].[InternalName] = 'labelname') AND ([c.Businesstransaction.DocumentType].[DocumentTypeName] = 'documenttype')) AND ([c.Businesstransaction.SourceSystem].[SourceSystemName] = 'sourcessysem')) AND ([CommunicationOutputChannels].[OutputChannel] = 'email')
对象 CommunicationOutputChannel
具有 ICollection<CommunicationStatusOutputChannel>
类型的导航 属性 CommunicationStatusOutputChannels
(CommunicationOutputChannel
和 CommunicationStatusOutputChannels
个实体)。
所以表 CommunicationOutputChannels
和 CommunicationStatusOutputChannels
之间的最后一个 INNER JOIN
应该是 CROSS APPLY
.
没关系。找到适合我的解决方案。
var q = from c in comCommunicationContext.Communication.Where(c=>c.Label.InternalName==labelName && c.Businesstransaction.DocumentType.DocumentTypeName==documentType && c.Businesstransaction.SourceSystem.SourceSystemName==sourceSystem)
join coc in comCommunicationContext.CommunicationOutputChannel
on c.CommunicationId equals coc.CommunicationId
from csoc in comCommunicationContext.CommunicationStatusOutputChannel.Where(x=>x.CommunicationOutputChannelId==coc.CommunicationOutputChannelId).OrderByDescending(y=>y.CreatedOn).Take(1)
where csoc.Status == "to process"
select new Communication(){CommunicationDataEnriched = c.CommunicationDataEnriched}
;