2009-02-05 57 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); 
}