我正在尝试根据传递给方法的一些动态/可选参数创建一个linq查询。
User [Table] -> zero to many -> Vehicles [Table]
User [Table] -> zero to many -> Pets
所以我们想要所有用户(包括任何vechile和/或宠物信息)。
是可选的过滤器因为车辆和宠物桌是零到多,所以我通常在用户桌和车辆桌之间有外连接。
为了加快查询速度,我试图创建动态linq,如果我们提供了一个可选参数,则将外部联接重新定义为内部联接。
(默认情况下,上下文关系图将两个表链接为外连接。)
可以这样做吗?
我也不确定this SO post是否可以帮助我。
答案 0 :(得分:1)
如果您尝试在运行时更改LINQ to SQL查询的表或联接,则需要使用反射来执行此操作。 LINQ表达式并不特殊;与使用任何其他对象调用相同 - 您可以在运行时更改属性和变量的值,但是选择要更改的属性或要调用的方法需要反映。
我想补充一点,指出通过反射动态创建LINQ表达式对于大多数(所有?)情况可能有点愚蠢,因为在底层表达式基本上反映回SQL语句。如果你是在运行中,也可以自己编写SQL。 LINQ的要点是从开发人员而不是最终用户抽象数据源。
答案 1 :(得分:1)
我认为你正走向错误的方向。您可以在此处轻松使用LINQ查询可组合的事实。
首先,您将始终使用外部联接,并使所有用户获得适当的车辆和宠物:
// Get all the users.
IQueryable<User> users = dbContext.Users;
然后,如有必要,您可以添加过滤器:
// If a filter on the pet name is required, filter.
if (!string.IsNullOrEmpty(petNameFilter))
{
// Filter on pet name.
users = users.Where(u => u.Pets.Where(
p => p.Name == petNameFilter).Any());
}
// Add a filter on the license plate number.
if (!string.IsNullOrEmpty(licensePlateFilter))
{
// Filter on the license plate.
users = users.Where(
u => u.Cars.Where(c => c.LicensePlace == licensePlateFilter).Any());
}
请注意,这将不过滤掉不符合过滤条件的宠物或汽车,因为它只是在寻找拥有该名称的宠物或带有该牌照的汽车的用户。
答案 2 :(得分:0)
这就是我如何做你要求的......
var results = u from dc.Users
join veh from dc.vehicles on u.userId equals v.userId into vtemp from v in vtemp.DefaultIfEmpty()
join pet from dc.pets on u.userId equals p.userId into ptemp from p in ptemp.DefaultItEmpty()
select new { user = u, vehicle = v, pet = p };
if ( !string.IsNullOrEmpty(petName) )
{
results = results.Where(r => r.pet.PetName == petName);
}
if ( !string.IsNullOrEmpty(licNum) )
{
results = results.Where(r => r.vehicle.LicNum == licNum);
}