Я пытаюсь преобразовать приведенный ниже SQL в построитель предикатов Entity Framework Core.
У меня есть 3 таблицы: Activity, WorkFlow, Applicant.
Activity
присоединен к WorkFlow
на WorkflowID
, но для него нет ограничения внешнего ключа. WorkFlow
содержит WorkFlowID
, который является основным, и ParentWorkFlowID
, который является просто обычным столбцом, но также имеет workflowId. WorkFlow
имеет ApplicantId
в качестве ограничения внешнего ключа. Applicant
не имеет ключа связи с любой другой таблицей
Я использую PredicateBuilder длясгенерировать приведенный ниже запрос, но не могу.
SELECT
wp.ApplicantID
,cra.ActivityID
,cra.[WorkflowID]
,cra.[Employed] as IsEmployed
,cra.[SelfEmployed] as IsSelfEmployed
,[BusName] as BusinessName
FROM
[dbo].[dActivity] cra
INNER JOIN
[dbo].[Workflow] wp ON (wp.ParentWorkflowID = cra.WorkflowID
AND wp.ApplicantID IN (1234, 5678))
Классы сущностей:
public class ActivityEntity
{
[Key]
public int? ActivityID { get; set; }
public int? WorkflowID { get; set; }
public WorkFlowEntity WorkflowProcess { get; set; }
public bool? Employed { get; set; }
public bool? SelfEmployed { get; set; }
public string BusName { get; set; }
public string BusAddress { get; set; }
public bool? BusActive { get; set; }
}
public class WorkFlowProcessEntity
{
[Key]
public int? WorkflowID { get; set; }
public IEnumerable<ApplicantEntity> Applicants { get; set; }
public int? ParentWorkflowID { get; set; }
public int? K2ProcessInstanceID { get; set; }
public int? OutcomeTypeID { get; set; }
}
public class ApplicantEntity
{
[Key]
public int? ApplicantID { get; set; }
public string Firstname { get; set; }
public string Middlename { get; set; }
public string FirstnameSoundex { get; set; }
public string SurnameSoundex { get; set; }
public string MiddlenameSoundex { get; set; }
public int? TitleID { get; set; }
}
Repository.cs:
public Task<List<ActivityEntity>> FindActivities(RequestModel requestModel)
{
IQueryable<ActivityEntity> query = _dbContext.Activity;
var builder = PredicateBuilder.New<ActivityEntity>();
if (requestModel.SearchCriteria?.ApplicantIds.Count > 0)
{
// This doesn't work
builder.And(v => v.WorkflowProcess.Applicants.Any(a => requestModel.SearchCriteria.ApplicantIds.Contains(a.ApplicantID)));
}
// Where
// order
// Offset
// Limit
query = query.Where(builder);
return query.OrderBy(a => a.ActivityID).AsExpandable().ToListAsync();
}
Это ответ, который я получаю от SQLПрофилировщик сервера:
exec sp_executesql N'SELECT [t].[ActivityID], [t].[ApplicantTypeID], [t].[BusActive], [t].[BusAddress], [t].[BusName], [t].[WorkflowProcessID]
FROM (
SELECT TOP(@__p_2) [x].[ActivityID], [x].[ApplicantTypeID], [x].[BusActive], [x].[BusAddress], [x].[BusName], [x].[WorkflowProcessID]
FROM [dbo].[Activity] AS [x]
LEFT JOIN [dbo].[Workflow] AS [x.Workflow] ON [x].[WorkflowID] = [x.Workflow].[WorkflowID]
WHERE ([x].[IsActive] = @__requestModel_SearchCriteria_IsActiveActivity_0) AND EXISTS (
SELECT 1
FROM [dbo].[Applicant] AS [a]
WHERE [a].[ApplicantID] IN (782094) AND ([x.Workflow].[WorkflowID] = [a].[WorkFlowEntityWorkflowID]))
) AS [t]
ORDER BY [t].[ActivityID]',N'@__p_2 int,@__requestModel_SearchCriteria_IsActiveActivity_0 bit',@__p_2=20,@__requestModel_SearchCriteria_IsActiveActivity_0=1