conversion - SQL to 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; }
}
dbContext.Items
.Where(x => x.Category.Name.Equals("Bread - Bakery"))
.Select(x => x.BrandID);

我不知道你为什么需要使用下面的join。似乎不需要(除非内部有意与品牌联合,从物品中删除不匹配的记录)

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

Hm,很遗憾您没有编写您的需求,现在我必须从您的SQL代码中猜测它们是什么。

因此,您有一个包含BrandsItemsCategories的数据库。每个Item都有一个Category,每个Category可以由零个或多个Items使用:一对多关系

每个Item都是某个Brand,每个Brand可以有零个或多个项:也是一个简单的一对多关系。

最后,每个Brand具有零个或多个Categories,每个Category具有零个以上Brands:多对多

现在您获取了Items的集合,您只想保留那些具有Name等于Bread - Bakery的Category的Items。从剩下的项目中,您需要它们的所有BrandId。

要求是:"给我所有有CategoryItems中的BrandIdsName等于‘面包店’。">

如果您使用实体框架,那么使用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

你确实意识到你的结果可能会有好几次相同的BrandId,不是吗?

如果你不想这样,从品牌开始:

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

换句话说:从品牌集合中,只保留那些至少有一个类别名称等于"面包-面包店"的品牌。从剩下的Brands中选择BrandId。

**备注2*

为什么是一对多列表而不是ICollections?你确定brand.Categories[4]有正确的含义吗?

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

编译器不会抱怨,但会出现运行时错误。

考虑将virtual ICollection<...>用于一对多和多对多关系。这样,您就可以获得数据库表所需的功能,如果您试图使用无法转换为SQL的功能,编译器会抱怨

相关内容

  • 没有找到相关文章

最新更新