2017-04-07 80 views
2

我們在應用程序中引入了一項新功能,該功能會影響數百個查詢。我們必須以非常複雜的方式設置bool字段以指示許可證是否有效。用可重用方法替換部分LINQ to SQL查詢

我想創建一個方法來返回這個bool值,我想在每個查詢中使用它。問題是,如果我按照下面所示的方式使用它,它會爲每個結果執行一個單獨的查詢。

如何使用Expression將其編譯爲SQL並作爲單個查詢執行?

原來的查詢,需要改進

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 
     ); 
} 

回答

0

如果設置的所述DataLoadOptionsDataContext在查詢並設置它們正確之前,應該避免子查詢。類似的東西:

db.LoadOptions.LoadWith<Devices>(p => p.License); 

Tha是默認行爲(實體的延遲加載)。你可以有更多的信息搜索'linq to sql eagerloading'

+0

我明白你是什麼暗示,但它不涉及我的問題。即使我在LINQ查詢中使用Entity.Entity.Entity,它仍將執行單個SQL查詢。 – Germstorm

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) => 
    ... 
}