2009-02-05 61 views
0

我想创建一个linq查询基于传递给一个方法的一些动态/可选参数。试图创建一些动态LINQ

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

因此,我们希望所有用户(包括任何vechile和/或宠物信息)。可选的过滤器是

  • 车辆号牌
  • 爱称

因为车辆和宠物表是零到很多,我通常有用户表和车辆之间的外部联接| pet表。

为了加快查询,我试图创建动态LINQ,如果我们有一个可选参数提供,将外连接重定义为内连接

(上下文图将有链接为外两个表默认情况下加入。)

可以这样做?

我也不能肯定是否this SO post能帮助我,无论是。

回答

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

注意这将而不是过滤掉不符合过滤器的宠物或汽车,因为它只是寻找拥有该名称的宠物的用户,或与该板的汽车。

+0

为什么ü在结束使用。任何()? – 2009-02-05 04:20:24

+0

@ Pure.Krome:因为您需要返回传递给第一次调用Where的predacate的布尔值。任何返回true/false并且将指示过滤器适用的宠物/汽车的存在。 – casperOne 2009-02-05 05:42:02

1

如果你试图改变表或在运行时的LINQ to SQL查询的连接,你需要做的是与反思。 LINQ表达式并不特别;与任何其他对象调用一样 - 您可以在运行时更改属性和变量的值,但要选择要更改哪些属性或调用哪些方法需要反映。

我想通过指出动态通过反射创建LINQ表达式添加到这可能是大多数(全部?)情况有点傻,因为引擎盖下的表达基本上反射回的SQL语句。如果你正在做这个动作,不妨自己写SQL。 LINQ的意义在于从开发者中抽象出数据源,而不是最终用户。

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