试图创建一些动态linq

时间:2009-02-05 03:11:47

标签: c# linq

我正在尝试根据传递给方法的一些动态/可选参数创建一个linq查询。

User [Table] -> zero to many -> Vehicles [Table]
User [Table] -> zero to many -> Pets

所以我们想要所有用户(包括任何vechile和/或宠物信息)。

是可选的过滤器
  • 车牌号
  • 宠物名称

因为车辆和宠物桌是零到多,所以我通常在用户桌和车辆桌之间有外连接。

为了加快查询速度,我试图创建动态linq,如果我们提供了一个可选参数,则将外部联接重新定义为内部联接

(默认情况下,上下文关系图将两个表链接为外连接。)

可以这样做吗?

我也不确定this SO post是否可以帮助我。

3 个答案:

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