2009-02-05 4 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

Почему и использовать .any() в конце? –

+0

@ Pure.Krome: потому что вам нужно вернуть логическое значение для predacate, которое передается при первом вызове Where. Любой возвращает true/false и указывает на наличие любимой машины/машины, к которой применяется фильтр. – casperOne

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

это использование внутренних соединений? –

Смежные вопросы