У меня есть запрос Linq-to-Entities, который не сложен, но требует .include и / или проекции и / или соединения, потому что он должен быть выполнен за один проход.
Вот моя база данных (Microsoft SQL Server 2008):
Таблица A (Клиенты) (содержит CustomerID (идентификаторы клиентов) и ZipCode (почтовые индексы) в виде строк.
Таблица C (Категории) (содержит CategoryID (категории), такие как «еда», «жилье», «одежда», «жилье» (первичные ключи).
Таблица A_C является таблицей связывания, поскольку таблицы A и C связаны как многие-ко-многим: содержит только два поля: CustomerID «идентификаторы клиента» и CategoryID (категории) в комбинации в качестве первичных ключей. Эта таблица является связующей таблицей между таблицами A и C.
Вот мой запрос, который должен быть выполнен всего за одну поездку в базу данных: мне нужно выбрать все записи в таблице A, которые удовлетворяют условию, а затем отфильтровать эти записи в зависимости от «списка параметров», которые находятся в Таблица связывания A_C - и все это за одну поездку в базу данных. Но я не знаю, какая длина или состав списка параметров для Таблицы A_C опережает время - она меняется от звонка к звонку. Таким образом, этот список параметров варьирует вызов метода путем вызова метода.
Чтобы привести более конкретный пример:
Таблица A содержит список идентификаторов клиентов. Я нахожу клиентов, которые живут в определенном почтовом индексе. Затем, в том же SQL-запросе , мне нужно выяснить, какие из этих клиентов выбрали определенные категории: продукты питания, одежда, жилье и т. Д., Но мой веб-метод не знает заранее, что это за категории, скорее они передаются методу в виде списка: List myCategoryList (который может быть 1 категорией или 100 категориями и может варьировать вызов метода при вызове метода).
Как мне написать проекцию, используя Linq-to-Entities? Когда список параметров меняется? И сделать все это за один проход?
List<string> CategoryList = new List<string>() { "Food", "Shelter", "Housing" }; // in one call to the web service method
List<string> CategoryList = new List<string>() { "Food", "Clothing" }; //could be a second call--it varies and I don't know ahead of time what the List will be
Так как я могу выполнить SQL-запрос, используя Linq-to-Entities? За один проход? (Конечно, я мог бы пройтись по списку и делать повторные поездки в базу данных, но мне сказали, что это не оптимальное решение). Проекция. Включая ключевые слова, но просмотр сети ничего не дал.
Вот грубое предположение, просто чтобы перекатить мяч:
public void WebMethod1 (CategoryList)
{
using (EntityFramework1 context = new EntityFramework1())
{
/* assume CategoryList is a list of strings passed into the method and is,for this particular call,something like: List<string> CategoryList = new List<string>() { "Food", "Clothing" }; for this call, but in the next call it could be: List<string> CategoryList = new List<string>() { "Food", "Shelter", "Housing" } */
string ZipCodeString = "12345";
string customerIDString = "E12RJ55";
var CustomersFromZipCodeHavingSelectedCertainCategories = from x in context.A_C
where x.A.CustomerID == customerIDString
where x.A.StartsWith(ZipCodeString)
where x.A_C.Contains(CategoryList) //???? This is clearly not grammatical, but what is?
select x;
}
/ *
Моя проблема: я хочу отфильтровать все записи из A, которые содержат почтовый индекс 12345, и которые также имеют определенный CustomerID "E12RJ55" из таблицы A, но дополнительно отфильтровать этот набор со всеми такими CustomerID в связующей таблице A_C, которые содержат категории "Еда" и "Одежда".
Как это сделать за один проход? Я могу сделать это довольно легко за несколько проходов и поездок в базу данных с помощью кода, но кто-то из этой ветки здесь http://bit.ly/rEG2AM предложил мне выполнить соединение / проекцию и сделать все это одним махом.
* /
Я также приму ответы на SQL, так как это может помочь найти решение. Мне кажется, этот вопрос не сложный, но я не смог найти ответ в сети.
РЕДАКТИРОВАТЬ: с ответом и кредитом Дэвиду с.
Я благодарю вас за ответ. Вот что сработало, немного отличаясь от ответа david.s, в том, что я использую таблицу связывания (таблица мостов) под названием «Customer_Categories», которая находится между таблицей Customer и Categories и содержит первичный ключ каждого (как требуется). для отношений многих ко многим). Эта таблица мостов - это то, что я назвал «A_C» в своем первоначальном ответе, и здесь есть целые числа, а не строки, но это то же самое. Intellisense взял эту таблицу, и я использовал ее, и она работает. Также имейте в виду, что CategoryList является списком целых чисел, List CategoryList = new List (); но удивительно, что он автоматически работает внутри этого запроса SQL-to-Entities:
Var CustomersFromZipCOde = context.Customers.Where (custo => custo.CustomerID==customerIDString && custo.ZipCode.StartsWith(ZipCodeString) && custo.Customer_Categories.Any(categ => CategoryList.Contains(categ.CategoryID)));
//gives the right output, incredible.