Преобразование SQL в Entity Framework Core для выполнения левых соединений с помощью In Condition - PullRequest
0 голосов
/ 05 октября 2018

Я пытаюсь преобразовать приведенный ниже 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
...