C# 将或转换为LINQ中的并集
LINQ查询中的OR子句导致性能问题。如果我把它改成工会绩效会提高很多。这是当前的查询。如何将C# 将或转换为LINQ中的并集,c#,sql,sql-server,linq,lambda,C#,Sql,Sql Server,Linq,Lambda,LINQ查询中的OR子句导致性能问题。如果我把它改成工会绩效会提高很多。这是当前的查询。如何将(includeBatch&&I.BatchId!=null | | includeSingle&&I.BatchId==null)这部分查询转换为Union 原始通话: var inputs = _inputRepository.GetProcessorQueue(includeBatch, includeSingle, companyIds); 当前解决方案:拨打两个电话并执行联合操作 if (
(includeBatch&&I.BatchId!=null | | includeSingle&&I.BatchId==null)
这部分查询转换为Union
原始通话:
var inputs = _inputRepository.GetProcessorQueue(includeBatch, includeSingle, companyIds);
当前解决方案:拨打两个电话并执行联合操作
if (includeSingle && includeBatch)
{
var inputsSingle = _inputRepository.GetProcessorQueue(false, includeSingle, companyIds);
var inputsBatch = _inputRepository.GetProcessorQueue(includeBatch, false, companyIds);
return inputsSingle.Union(inputsBatch).ToList();
}
else
{
var inputs = _inputRepository.GetProcessorQueue(includeBatch, includeSingle, companyIds);
return inputs.Select(Input.ToQueueInputExpression(inputQueueMetaDataTypes)).ToList();
}
原始LINQ:
public IQueryable<Input> GetProcessorQueue(bool includeBatch, bool includeSingle, int[] companyIds)
{
return FindAsQueryableReadOnly(i => !i.IsDeleted
&& i.InputTypeId == (int)InputType.Values.TRANSPORTATION
&& i.ExportedStatusId != (int)ExportedStatus.Values.EXPORTED
&& ImportStatus.DataEntryQueue.Contains(i.ImportStatusId)
&& ((i.TransportationInput.TransportationInputTypeId == (int)TransportationInputType.Values.FACTOR
&& (includeBatch && i.BatchId != null || includeSingle && i.BatchId == null)
&& !i.DocumentOnlyStatus)
|| (includeBatch && i.BatchId != null && i.DocumentOnlyStatus && i.InputDocumentStats.DocumentId != null)
)
&& (companyIds == null || !companyIds.Any() || companyIds.Contains(i.CompanyId)),
i => i.Batch,
i => i.ImportStatus,
i => i.InputCharges,
i => i.InputDocumentStats,
i => i.InputDocumentStats.DocumentOrigin,
i => i.InputDocumentStats.Document.DocumentMetaData);
}
public IQueryable GetProcessorQueue(bool includeBatch,bool includeSingle,int[]公司ID)
{
返回FindAsQueryableReadOnly(i=>!i.IsDeleted
&&i.InputTypeId==(int)InputType.Values.TRANSPORTATION
&&i.ExportedStatusId!=(int)ExportedStatus.Values.EXPORTED
&&ImportStatus.DataEntryQueue.Contains(i.ImportStatusId)
&&((i.TransportationInput.TransportationInputTypeId==(int)TransportationInputType.Values.FACTOR
&&(includeBatch&i.BatchId!=null | | includeSingle&i.BatchId==null)
&&!i.DocumentOnlyStatus)
||(includeBatch&&i.BatchId!=null&&i.DocumentOnlyStatus&&i.InputDocumentStats.DocumentId!=null)
)
&&(CompanyId==null | | |!CompanyId.Any()| | CompanyId.Contains(i.CompanyId)),
i=>i.批次,
i=>i.ImportStatus,
i=>i.输入费用,
i=>i.InputDocumentStats,
i=>i.InputDocumentStats.DocumentOrigin,
i=>i.InputDocumentStats.Document.DocumentMetaData);
}
原始SQL:(为了可读性删除了select语句)
来自[eroom]。[Input]作为[i]
将[eroom].[ImportStatus]作为[i].[ImportStatusId]=[i.ImportStatus].[ImportStatusId]上的[i.ImportStatus]进行内部联接
在[i].[BatchId]=[i.Batch].[BatchId]上以[i.Batch]的身份左键加入[eroom].[Batch]
左键将[eroom].[InputDocumentStats]作为[i].[InputId]=[i.InputDocumentStats].[InputId]上的[i.InputDocumentStats]加入
在[i.InputDocumentStats].[DocumentOriginId]=[i.InputDocumentStats.DocumentOrigin]上以[i.InputDocumentStats.DocumentOrigin]的身份左键加入[eroom].[DocumentOrigin]
在[i.InputDocumentStats].[DocumentId]=[i.InputDocumentStats.Document].[i.InputDocumentStats.Document]上以[i.InputDocumentStats.Document]的身份左键加入[eroom].[Document]
将[eroom].[TransportationInput]作为[i].[InputId]=[i.TransportationInput].[InputId]上的[i.TransportationInput]左键加入[i.TransportationInput]
其中((([i].[HiddenStatus]=0)和([i].[InputTypeId]=1)和([i].[ExportedStatusId]3)和[i].[ImportStatusId]在(1,4,5,7)中)和(([i.TransportationInput].[TransportationInputTypeId]=1)和([i].[BatchId]不为空或[i].[BatchId]为空)和([i].[DocumentOnlyStatus]=0])或([i].[BatchId]不为空且([i])。(1,2,3)中的[DocumentOnlyStatus]=1)和[i.InputDocumentStats].[DocumentId]不为空])和[i].[CompanyId]
性能更好的SQL(删除select语句以提高可读性)
来自[eroom]。[Input]作为[i]
将[eroom].[ImportStatus]作为[i].[ImportStatusId]=[i.ImportStatus].[ImportStatusId]上的[i.ImportStatus]进行内部联接
在[i].[BatchId]=[i.Batch].[BatchId]上以[i.Batch]的身份左键加入[eroom].[Batch]
左键将[eroom].[InputDocumentStats]作为[i].[InputId]=[i.InputDocumentStats].[InputId]上的[i.InputDocumentStats]加入
在[i.InputDocumentStats].[DocumentOriginId]=[i.InputDocumentStats.DocumentOrigin]上以[i.InputDocumentStats.DocumentOrigin]的身份左键加入[eroom].[DocumentOrigin]
在[i.InputDocumentStats].[DocumentId]=[i.InputDocumentStats.Document].[i.InputDocumentStats.Document]上以[i.InputDocumentStats.Document]的身份左键加入[eroom].[Document]
将[eroom].[TransportationInput]作为[i].[InputId]=[i.TransportationInput].[InputId]上的[i.TransportationInput]左键加入[i.TransportationInput]
式中,(([i].[HiddenStatus]=0)和([i].[InputTypeId]=1)和([i].[ExportedStatusId]3)和[i].[ImportStatusId]在(1,4,5,7)中)和(([i.TransportationInput].[TransportationInputTypeId]=1)和[i].[BatchId]不为空)和([i].[DocumentOnlyStatus]=0))或([i].[BatchId]不为空且([i].[DocumentOnlyStatus]=1])(1,2,3)中的[i.InputDocumentStats].[DocumentId]不为空)和[i].[CompanyId]
联合
来自[eroom]。[Input]作为[i]
将[eroom].[ImportStatus]作为[i].[ImportStatusId]=[i.ImportStatus].[ImportStatusId]上的[i.ImportStatus]进行内部联接
在[i].[BatchId]=[i.Batch].[BatchId]上以[i.Batch]的身份左键加入[eroom].[Batch]
左键将[eroom].[InputDocumentStats]作为[i].[InputId]=[i.InputDocumentStats].[InputId]上的[i.InputDocumentStats]加入
在[i.InputDocumentStats].[DocumentOriginId]=[i.InputDocumentStats.DocumentOrigin]上以[i.InputDocumentStats.DocumentOrigin]的身份左键加入[eroom].[DocumentOrigin]
在[i.InputDocumentStats].[DocumentId]=[i.InputDocumentStats.Document].[i.InputDocumentStats.Document]上以[i.InputDocumentStats.Document]的身份左键加入[eroom].[Document]
将[eroom].[TransportationInput]作为[i].[InputId]=[i.TransportationInput].[InputId]上的[i.TransportationInput]左键加入[i.TransportationInput]
其中((([i].[HiddenStatus]=0)和([i].[InputTypeId]=1)和([i].[ExportedStatusId]3)和[i].[ImportStatusId]在(1,4,5,7)中)和(([i.TransportationInput].[TransportationInputTypeId]=1)和[i].[BatchId]为空)和([i].[DocumentOnlyStatus]=0])和[i].[CompanyId]在(1,2,3)中)
public IQueryable FindAsQueryableReadOnly(表达式,其中,参数表达式[]包含属性)
{
IQueryable查询=_dbSet.AsQueryable();
查询=IncludeProperty(IncludeProperty,查询);
返回query.Where(Where.AsNoTracking();
}
为什么不只调用一个存储过程呢?这在这个公司是不允许的。这行是不是inputsSingle.Union(inputsBatch.ToList());
不返回带有union的select?它会抛出一个错误。下面是它调用的方法FindAsQueryableReadOnly@Luci您的查询是否有效,或者您仅在使用union
时出现此错误?请编辑您的问题,以便
FROM [eroom].[Input] AS [i]
INNER JOIN [eroom].[ImportStatus] AS [i.ImportStatus] ON [i].[ImportStatusId] = [i.ImportStatus].[ImportStatusId]
LEFT JOIN [eroom].[Batch] AS [i.Batch] ON [i].[BatchId] = [i.Batch].[BatchId]
LEFT JOIN [eroom].[InputDocumentStats] AS [i.InputDocumentStats] ON [i].[InputId] = [i.InputDocumentStats].[InputId]
LEFT JOIN [eroom].[DocumentOrigin] AS [i.InputDocumentStats.DocumentOrigin] ON [i.InputDocumentStats].[DocumentOriginId] = [i.InputDocumentStats.DocumentOrigin].[DocumentOriginId]
LEFT JOIN [eroom].[Document] AS [i.InputDocumentStats.Document] ON [i.InputDocumentStats].[DocumentId] = [i.InputDocumentStats.Document].[DocumentId]
LEFT JOIN [eroom].[TransportationInput] AS [i.TransportationInput] ON [i].[InputId] = [i.TransportationInput].[InputId]
WHERE ((((([i].[HiddenStatus] = 0) AND ([i].[InputTypeId] = 1)) AND ([i].[ExportedStatusId] <> 3)) AND [i].[ImportStatusId] IN (1, 4, 5, 7)) AND (((([i.TransportationInput].[TransportationInputTypeId] = 1) AND ([i].[BatchId] IS NOT NULL OR [i].[BatchId] IS NULL)) AND ([i].[DocumentOnlyStatus] = 0)) OR (([i].[BatchId] IS NOT NULL AND ([i].[DocumentOnlyStatus] = 1)) AND [i.InputDocumentStats].[DocumentId] IS NOT NULL))) AND [i].[CompanyId] IN (1, 2, 3)
FROM [eroom].[Input] AS [i]
INNER JOIN [eroom].[ImportStatus] AS [i.ImportStatus] ON [i].[ImportStatusId] = [i.ImportStatus].[ImportStatusId]
LEFT JOIN [eroom].[Batch] AS [i.Batch] ON [i].[BatchId] = [i.Batch].[BatchId]
LEFT JOIN [eroom].[InputDocumentStats] AS [i.InputDocumentStats] ON [i].[InputId] = [i.InputDocumentStats].[InputId]
LEFT JOIN [eroom].[DocumentOrigin] AS [i.InputDocumentStats.DocumentOrigin] ON [i.InputDocumentStats].[DocumentOriginId] = [i.InputDocumentStats.DocumentOrigin].[DocumentOriginId]
LEFT JOIN [eroom].[Document] AS [i.InputDocumentStats.Document] ON [i.InputDocumentStats].[DocumentId] = [i.InputDocumentStats.Document].[DocumentId]
LEFT JOIN [eroom].[TransportationInput] AS [i.TransportationInput] ON [i].[InputId] = [i.TransportationInput].[InputId]
WHERE ((((([i].[HiddenStatus] = 0) AND ([i].[InputTypeId] = 1)) AND ([i].[ExportedStatusId] <> 3)) AND [i].[ImportStatusId] IN (1, 4, 5, 7)) AND (((([i.TransportationInput].[TransportationInputTypeId] = 1) AND [i].[BatchId] IS NOT NULL) AND ([i].[DocumentOnlyStatus] = 0)) OR (([i].[BatchId] IS NOT NULL AND ([i].[DocumentOnlyStatus] = 1)) AND [i.InputDocumentStats].[DocumentId] IS NOT NULL))) AND [i].[CompanyId] IN (1, 2, 3)
UNION
FROM [eroom].[Input] AS [i]
INNER JOIN [eroom].[ImportStatus] AS [i.ImportStatus] ON [i].[ImportStatusId] = [i.ImportStatus].[ImportStatusId]
LEFT JOIN [eroom].[Batch] AS [i.Batch] ON [i].[BatchId] = [i.Batch].[BatchId]
LEFT JOIN [eroom].[InputDocumentStats] AS [i.InputDocumentStats] ON [i].[InputId] = [i.InputDocumentStats].[InputId]
LEFT JOIN [eroom].[DocumentOrigin] AS [i.InputDocumentStats.DocumentOrigin] ON [i.InputDocumentStats].[DocumentOriginId] = [i.InputDocumentStats.DocumentOrigin].[DocumentOriginId]
LEFT JOIN [eroom].[Document] AS [i.InputDocumentStats.Document] ON [i.InputDocumentStats].[DocumentId] = [i.InputDocumentStats.Document].[DocumentId]
LEFT JOIN [eroom].[TransportationInput] AS [i.TransportationInput] ON [i].[InputId] = [i.TransportationInput].[InputId]
WHERE ((((([i].[HiddenStatus] = 0) AND ([i].[InputTypeId] = 1)) AND ([i].[ExportedStatusId] <> 3)) AND [i].[ImportStatusId] IN (1, 4, 5, 7)) AND ((([i.TransportationInput].[TransportationInputTypeId] = 1) AND [i].[BatchId] IS NULL) AND ([i].[DocumentOnlyStatus] = 0))) AND [i].[CompanyId] IN (1, 2, 3)
public IQueryable<T> FindAsQueryableReadOnly(Expression<Func<T, bool>> where, params Expression<Func<T, object>>[] includeProperties)
{
IQueryable<T> query = _dbSet.AsQueryable();
query = IncludeProperties(includeProperties, query);
return query.Where(where).AsNoTracking();
}