Преобразование - SQL в LINQ

Как можно выполнить следующее, используя LINQ

SELECT r.BrandID 
FROM dbo.Items AS r
JOIN Brands AS d ON r.BrandID = d.BrandID
WHERE CategoryID IN (SELECT CategoryID 
                     FROM dbo.Categories
                     WHERE Name = 'Bread - Bakery')

Код для Brand учебный класс:

public class Brand
{
    public int BrandID { get; set; }
    [DisplayName("Brand Name")]
    public string Name { get; set; }
    public virtual List<Category> Categories { get; set; }
    public virtual List<Item> Items { get; set; }
}

Код для Item учебный класс:

public class Item
{
    [Key]
    public int ItemID { get; set; }
    public virtual Category Category { get; set; }
    public virtual Brand Brand { get; set; }
    public int CategoryID { get; set; }
    public int BrandID { get; set; }
}

код для Category учебный класс:

public class Category
{
    [Key]
    public int CategoryID { get; set; }
    [DisplayName("Category Name")]
    public virtual string Name { get; set; }
    public virtual List<Brand> Brands { get; set; }
    public virtual List<Item> Items { get; set; }
}

2 ответа

Решение
dbContext.Items
  .Where(x => x.Category.Name.Equals("Bread - Bakery"))
  .Select(x => x.BrandID);

Я не уверен, почему вам нужно использовать ниже присоединиться. Кажется, что это не нужно (если только намеренно не объединить с брендами, чтобы удалить несоответствующие записи из предметов)

JOIN Brands AS d ON r.BrandID = d.BrandID

Хм, жаль, что вы не написали свои требования, теперь я должен догадаться, что они из вашего кода SQL.

Итак, у вас есть база данных с Brands, Items а также Categories, каждый Item имеет Categoryкаждый Category может использоваться нулем или больше Items: отношение один ко многим

каждый Item имеет определенный BrandКаждый Brand может иметь ноль или более элементов: также прямое отношение "один ко многим".

Наконец каждый Brand имеет ноль или более Categoriesкаждый Category имеет ноль или более Brands: многие ко многим

Теперь вы берете свою коллекцию ItemsВы только хотите сохранить эти Items которые имеют категорию с Name это равно Bread - Bakery, Из оставшихся предметов вам нужны все их фирменные идентификаторы.

Требование было бы: "Дай мне BrandIds из всех Items которые имеют Category с Name что равно "Хлеб - Пекарня".

Если вы используете платформу сущностей, обычно проще, если вы используете virtual ICollection вместо того, чтобы делать соединение самостоятельно. Платформа сущностей знает отношения между таблицами и будет составлять правильные соединения для нее.

var result = myDbContext.Items                             // from the collection of Items
    .Where(item => item.Category.Name == "Bread - Bakery") // keep only those with a Category
                                                           // that has a Name equal to ...
    .Select(item.BrandId);                        // from the remaining items select the BrandId

Если вы действительно хотите и можете убедить своего руководителя проекта в том, что инфраструктуре сущностей нельзя доверять для правильного объединения, вы можете сделать это самостоятельно:

// get the sequence of categories that I'm interested in:
var breadBakeryCategories = myDbContext.Categories
    .Where(category => category.Name == "Bread - Bakery");

// join the items with these categories
// and select the BrandIds
var requestedBrandIds= myDbContext.Items
    .Join(breadBakeryCategories,
    item => item.CategoryId,           // from every Item take the CategoryId,
    category => category.CategoryId,   // from every Category take the CategoryId
    (item, category) => item.BrandId);   // when they match, select the BrandId

TODO: рассмотрите возможность объединения этого в одно большое уродливое утверждение LINQ.

Замечание 1

Вы понимаете, что ваш результат может иметь один и тот же BrandIds несколько раз, не так ли?

Если вы не хотите этого, начните с брендов:

var result = myDbContext.Brands
.Where(brand => brand.Items.Select(item => item.Category.Name)
                .Where(name => name == "Bread - Bakery")
                .Any())
.Select(brand => brand.brandId);

На словах: из коллекции брендов сохраните только те бренды, которые имеют хотя бы одну категорию с именем, равным "Хлеб - Пекарня". Из оставшихся брендов выберите BrandId.

** Замечание 2 **

Почему ваши списки один-ко-многим вместо ICollections? Вы уверены, что brand.Categories[4] имеет правильное значение?

var result = myDbContext.Brands
    .Where(brand => brand.Category[4].Name == "Bread - Bakeries");

Ваш компилятор не будет жаловаться, но вы получите ошибки во время выполнения.

Рассмотреть возможность использования virtual ICollection<...> для ваших отношений один ко многим и многие ко многим. Таким образом, вы получите именно ту функциональность, которую ожидаете от таблицы базы данных, и ваш компилятор будет жаловаться, если вы попытаетесь использовать функциональность, которая не может быть преобразована в SQL

Другие вопросы по тегам