[英]Replace part of a LINQ to SQL query with a reusable method
我们在应用程序中引入了一项新功能,该功能会影响数百个查询。 我们必须设置一个bool
字段以非常复杂的方式指示许可证是否有效。
我想创建一个返回此bool
值的方法,并且希望在每个查询中使用它。 问题是,如果我以下面所示的方式使用它,它将为每个结果执行一个单独的查询。
如何使用将Expression
编译成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
)
};
checkForLicense
是一个bool
,指示不需要检查许可证。 在某些情况下使用它,有必要加以考虑。
代码可以解决问题,但会为每个设备引发一个单独的查询
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
);
}
如果在查询之前设置DataContext
的DataLoadOptions
并正确设置它们,则应避免使用subselect。 类似于以下内容:
db.LoadOptions.LoadWith<Devices>(p => p.License);
Tha是默认行为(实体的延迟加载)。 您可能需要更多信息来搜索“ linq to sql eagerloading”
不确定是否可以使用,但是您是否尝试在主查询中访问许可证? 换句话说:
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) =>
...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.