Простой запрос Linq-to-entity, включающий .Include, я полагаю - PullRequest
0 голосов
/ 20 ноября 2011

У меня есть запрос 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.

1 Ответ

3 голосов
/ 20 ноября 2011

Прежде всего, я хотел бы сказать, что даже если ваше объяснение очень длинное, оно не очень понятно. Вам нужен простой запрос Linq-to-Entities, но вы не даете Entities, вы говорите только о таблицах в вашей базе данных.

Предполагается, что у вас есть следующие объекты:

public class Customer
{
    public string CustomerID { get; set; }
    public string ZipCode { get; set; }
    public virtual ICollection<Category> Categories { get; set; }
}

public class Category
{
    public string CategoryID { get; set; }
    public virtual ICollection<Customer> Customers { get; set; }
}

Ваш запрос может выглядеть следующим образом:

var CustomersFromZipCodeHavingSelectedCertainCategories =
    context.Customers.Where(
        customer => customer.CustomerID == customerIDString &&
                    customer.ZipCode.StartsWith(ZipCodeString) &&
                    customer.Categories.Any(
                        category => CategoryList.Contains(category.CategoryID));

Подробнее о других способах сделать это здесь: http://smehrozalam.wordpress.com/2010/06/29/entity-framework-queries-involving-many-to-many-relationship-tables/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...