使用可重用方法替换LINQ to SQL查询的一部分

时间:2017-04-07 07:09:08

标签: c# linq linq-to-sql

我们在应用程序中引入了一项新功能,它会影响数百个查询。我们必须设置一个bool字段,以非常复杂的方式指示许可证是否有效。

我想创建一个返回此bool值的方法,并且我想在每个查询中使用它。问题是,如果我以下面显示的方式使用它,它会为每个结果执行单独的查询。

如何以编译为SQL并作为单个查询执行的方式使用Expression

原始查询,需要改进

IQueryable<DeviceMinimal> devices = 
    from device in db.Devices
    where device.AccountId = accountId

    select new DeviceMinimal
    {
        Id = device.Id,
        Name = device.Name,
        LicenseIsValid = !checkForLicense || 
            device.License != null && (
                !device.License.TrialStarted
                // && 12+ licensing rules
            )
    };

checkForLicensebool,表示不需要检查许可证。它在某些情况下使用,有必要加以考虑。

解决问题的代码,但会为每个设备引发单独的查询

IQueryable<DeviceMinimal> devices = 
    from device in db.Devices
    where device.AccountId = accountId

    select new DeviceMinimal
    {
        Id = device.Id,
        Name = device.Name,
        LicenseIsValid = 
            LicenseHelper.IsLicenseValid(checkForLicense).Invoke(device)
    };

上述查询中使用的方法:

public static Func<Device, bool> IsLicenseEnabledAndValid(bool checkForLicense)
{
    return result => !checkForLicense ||                 
        result.License != null && (
            !result.License.TrialStarted
            // && 12+ licensing rules
        );
}

2 个答案:

答案 0 :(得分:0)

如果您在查询之前设置DataLoadOptions的{​​{1}}并将其设置正确,则应避免使用子选择。类似的东西:

DataContext

Tha是默认行为(实体的延迟加载)。您可以获取更多信息,搜索&#39; linq到sql eagerloading&#39;

答案 1 :(得分:0)

不确定它是否可行,但您是否尝试在主查询中访问许可证? 换句话说就像:

Queryable<DeviceMinimal> devices =
   from device in db.Devices
   where device.AccountId = accountId

   select new DeviceMinimal
   {
       Id = device.Id,
       Name = device.Name,
       LicenseIsValid =
        LicenseHelper.IsLicenseEnabledAndValid(checkForLicense).Invoke(device.Licence)
   };

public static Func<License, bool> IsLicenseEnabledAndValid(bool checkForLicense)
{
    return result => !checkForLicense ||
        result != null && (
       !result.TrialStarted
        // && 12+ licensing rules
      );
}

如果您需要在方法中同时访问设备和许可证,则可能需要将功能更改为

public static Func<Device, License, bool> IsLicenseEnabledAndValid(bool checkForLicense)
{
   return (device, licence) =>  
  ...
}