【问题标题】:Adding a non-SQL where clause to LINQ-2-SQL向 LINQ-2-SQL 添加非 SQL where 子句
【发布时间】:2011-03-15 16:56:13
【问题描述】:

我有一个 Linq-2-SQL,它在内部 foreach 循环之前更新 IEnumerable<Locum> LeftOverLocums。我需要在Where 部分再添加一个布尔子句,但它与SQL DB 无关。事实上,它是一个效用函数。请看下面的两个函数。第一个是主要功能,第二个是我需要嵌入到Where部分的那个。

    private void PreferenceFindJobs(ref JobCustomList jobList) {
        List<KeyValuePair<long, DateTime>> AlreadyPrefferedLocums = new List<KeyValuePair<long, DateTime>>();

        List<long> LocumsFilteringIDs = SchedulerMatrixStorage.Resources.Items.Select(col => Convert.ToInt64(col.Id)).ToList();

        IEnumerable<Locum> LeftOverLocums = null;

        foreach (JobCustom oneJob in jobList) {

            LeftOverLocums = from locums in DbContext.Locums
                                             join availabilities in DbContext.Availabilities on new {
                                                 OID = locums.OID
                                             } equals new {
                                                 OID = availabilities.LocumID
                                             }
                                             where
                                               LocumsFilteringIDs.Contains(locums.OID) &&
                                               locums.IsActive == true &&
                                               locums.IsLocumsExciteBan == false &&
                                               locums.IsGPHCBan == false &&
                                               locums.IsRPSGBBan == false &&
                                               locums.IsAdminMarkedComplete == true &&
                                               availabilities.AvailabilityStatusID == 1 &&
                                               availabilities.AvailableDate == oneJob.JobDate
                                             select locums;

            foreach (Locum oneLocum in LeftOverLocums) {
                    //This Locum can do this job

                    //Now check if he/she has been just alloted
                    if (AlreadyPrefferedLocums.Any(check => check.Key == oneLocum.OID && check.Value == oneJob.JobDate) == false) {
                        //No? Cool!
                        oneJob.LocumID = oneLocum.OID;
                        oneJob.LocumName = oneLocum.FirstName + " " + oneLocum.LastName;

                        //Add to the list to prevent double allocation
                        AlreadyPrefferedLocums.Add(new KeyValuePair<long, DateTime>(oneJob.LocumID, oneJob.JobDate));

                    } else {
                        continue;

                    }

            }

        }
    }

    public enum LocumType {
        Pharmacist = 1,
        Dispenser = 2,
        AccreditedCheckingTechnician = 3
    }

    public static Boolean IsJobTypeOK(Enumerations.LocumType _Job, Enumerations.LocumType _Locum) {
        bool ProcessResult;

        switch (_Job) {
            case  Enumerations.LocumType.Pharmacist:
            ProcessResult = _Locum == Enumerations.LocumType.Pharmacist;
            break;

            case Enumerations.LocumType.Dispenser:
            ProcessResult = _Locum == Enumerations.LocumType.Dispenser;
            break;

            case Enumerations.LocumType.AccreditedCheckingTechnician:
            ProcessResult = _Locum == Enumerations.LocumType.AccreditedCheckingTechnician || _Locum == Enumerations.LocumType.Dispenser;
            break;

            default:
            ProcessResult = false;
            break;
        }

        return ProcessResult;
    }

这是我想要的Where 子句:

where
    IsJobTypeOK(oneJob.JobTypeID, locums.LocumTypeID) &&
    LocumsFilteringIDs.Contains(locums.OID) &&
    locums.IsActive == true &&
    locums.IsLocumsExciteBan == false &&
    locums.IsGPHCBan == false &&
    locums.IsRPSGBBan == false &&
    locums.IsAdminMarkedComplete == true &&
    availabilities.AvailabilityStatusID == 1 &&
    availabilities.AvailableDate == oneJob.JobDate

【问题讨论】:

  • 我看不出这里有什么问题?您可以在 where 子句中调用实用程序方法。也许用你得到什么错误或什么来更新问题?
  • 据我了解,LINQ2SQL 中的 Where 子句仅需要与 SQL 服务器相关的查询。
  • Hassan,你是对的,LINQ 2 SQL 不能用于执行你的函数。因为查询必须在 SQL Server 中执行。 SQL 服务器无权访问您的方法。

标签: winforms linq-to-sql c#-4.0


【解决方案1】:

您根本不必使用“IsJobTypeOK”方法。


where
(
  (oneJob.JobTypeID == Enumerations.LocumType.AccreditedCheckingTechnician && 
     locums.LocumTypeID == Enumerations.LocumType.Dispenser) || 
  oneJob.JobTypeID == locums.LocumTypeID
) &&
LocumsFilteringIDs.Contains(locums.OID) &&
locums.IsActive == true &&
locums.IsLocumsExciteBan == false &&
locums.IsGPHCBan == false &&
locums.IsRPSGBBan == false &&
locums.IsAdminMarkedComplete == true &&
availabilities.AvailabilityStatusID == 1 &&
availabilities.AvailableDate == oneJob.JobDate

【讨论】:

  • 如果您查看 IsJobTypeOK() 方法,您会发现它不是简单的 'locums.LocumTypeID == oneJob.JobTypeID'
  • 如果您再次查看您的方法 IsJobTypeOK(),则返回 true 的唯一方法是当 JobType 与您的 locum.LocumTypeID 相同时,除非 JobTypeID 是不同的枚举,但您正在使用两个参数的类型完全相同。
  • 请看最后的Case声明
  • 好的,我明白了,那你可以where ((oneJob.JobTypeID == AccreditedCheckingTechnician &amp;&amp; locums.LocumTypeID == Dispenser) || oneJob.JobTypeID == locums.LocumTypeID) &amp;&amp; ...
【解决方案2】:

执行此操作的最佳方法是在从数据库调用结果后过滤结果。

//Get you LeftOverLocums like you are now
//then
LeftOverLocums = LeftOverLocums
                 .Where(l => l.IsJobTypeOK(oneJob.JobTypeID, l.LocumTypeID))

不需要任何额外的数据库

【讨论】:

  • 可能需要从数据库中提取不必要的记录才能在处理机中运行此功能。如果 SQL Server 可以处理整个查询,则将其传递给 SQL。这取决于您正在处理多少条记录。
猜你喜欢
  • 2014-10-30
  • 2011-05-30
  • 2015-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-21
  • 1970-01-01
相关资源
最近更新 更多