实体框架(Entity Framework )是 ADO.NET 中的一套支持开发面向数据的软件应用程序的技术。
LINQ to Entities 提供语言集成查询 (LINQ) 支持,它允许开发人员使用 Visual Basic 或 Visual C# 根据实体框架概念模型编写查询。针对实体框架的查询由针对对象上下文执行的命令目录树查询表示。LINQ to Entities 将语言集成查询 (LINQ) 查询转换为命令目录树查询,针对实体框架执行这些查询,并返回可同时由实体框架和 LINQ 使用的对象。
下面列出一些基于方法的查询语法示例(C#):
投影 |
筛选 |
排序 |
聚合运算符 | | | | |
分区 |
转换 | |
联接运算符 |
元素运算符
分组
Select
以下示例使用 Select 方法以将 Product.Name 和 Product.ProductID 属性投影到一系列匿名类型。
12345678910111213141516 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ var query = AWEntities.Products .Select(product => new { ProductId = product.ProductID, ProductName = product.Name }); Console.WriteLine("Product Info:"); foreach (var productInfo in query) { Console.WriteLine("Product Id: {0} Product name: {1} ", productInfo.ProductId, productInfo.ProductName); }} |
以下示例使用 Select 方法以只返回一系列产品名称。
1234567891011 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ IQueryable |
SelectMany
以下示例使用 SelectMany 方法以选择 TotalDue 低于 500.00 的所有订单。
1234567891011121314151617181920212223242526 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
以下示例使用 SelectMany 方法以选择在 2002 年 10 月 1 或此日期之后发出的所有订单。
1234567891011121314151617181920212223242526 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
Where
以下示例返回所有联机订单。
1234567891011121314 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ var onlineOrders = AWEntities.SalesOrderHeaders .Where(order => order.OnlineOrderFlag == true) .Select(s => new { s.SalesOrderID, s.OrderDate, s.SalesOrderNumber }); foreach (var onlineOrder in onlineOrders) { Console.WriteLine("Order ID: {0} Order date: {1:d} Order number: {2}", onlineOrder.SalesOrderID, onlineOrder.OrderDate, onlineOrder.SalesOrderNumber); }} |
以下示例返回订单数量大于 2 且小于 6 的订单。
123456789101112 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ var query = AWEntities.SalesOrderDetails .Where(order => order.OrderQty > 2 && order.OrderQty < 6) .Select(s => new { s.SalesOrderID, s.OrderQty }); foreach (var order in query) { Console.WriteLine("Order ID: {0} Order quantity: {1}", order.SalesOrderID, order.OrderQty); }} |
以下示例返回所有红色产品。
1234567891011121314 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ var query = AWEntities.Products .Where(product => product.Color == "Red") .Select(p => new { p.Name, p.ProductNumber, p.ListPrice }); foreach (var product in query) { Console.WriteLine("Name: {0}", product.Name); Console.WriteLine("Product number: {0}", product.ProductNumber); Console.WriteLine("List price: ${0}", product.ListPrice); Console.WriteLine(""); }} |
Where…Contains
以下示例将一个数组用作 Where¡Contains 子句的一部分,以查找 ProductModelID 与数组中的值匹配的所有产品。
1234567891011 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ int?[] productModelIds = { 19, 26, 118 }; var products = AWEntities.Products. Where(p => productModelIds.Contains(p.ProductModelID)); foreach (var product in products) { Console.WriteLine("{0}: {1}", product.ProductModelID, product.ProductID); }} |
作为 Where¡Contains 子句中谓词的一部分,您可以使用 Array、List<(Of <(<'T>)>)> 或实现IEnumerable<(Of <(<'T>)>)> 接口的任何类型的集合。 还可以在 LINQ to Entities 查询中声明和初始化集合。
以下示例声明并初始化 Where¡Contains 子句中的数组,以查找 ProductModelID 或 Size 与数组中的值匹配的所有产品。
12345678910111213 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ var products = AWEntities.Products. Where(p => (new int?[] { 19, 26, 18 }).Contains(p.ProductModelID) || (new string[] { "L", "XL" }).Contains(p.Size)); foreach (var product in products) { Console.WriteLine("{0}: {1}, {2}", product.ProductID, product.ProductModelID, product.Size); }} |
ThenBy
采用基于方法的查询语法的以下示例使用 OrderBy 和 ThenBy 以返回先按姓氏后按名字排序的联系人列表。
12345678910111213 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ IQueryable |
ThenByDescending
以下示例使用 OrderBy 和 ThenByDescending 方法以首先按标价排序,然后执行产品名称的降序排序。
12345678910111213141516 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
Average
以下示例使用 Average 方法来查找产品的平均标价。
12345678910 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
以下示例使用 Average 方法以查找每种样式的产品的平均标价。
12345678910111213141516171819 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
以下示例使用 Average 方法以查找平均应付款总计。
1234567 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
以下示例使用 Average 方法以获取每个联系人 ID 的平均应付款总计。
12345678910111213141516171819 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
以下示例使用 Average 方法以针对每个联系人获取具有平均应付款总计的订单。
1234567891011121314151617181920212223242526 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
Count
以下示例使用 Count 方法以返回 Product 表中的产品数量。
12345678 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
以下示例使用 Count 方法以返回联系人 ID 的列表和每个联系人 ID 所具有的订单数。
1234567891011121314151617181920 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
以下示例按颜色对产品进行分组,并使用 Count 方法以返回每个颜色组中的产品数量。
12345678910111213141516 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
LongCount
以下示例以长整型获取联系人计数。
1234567 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
Max
以下示例使用 Max 方法以获取最大应付款总计。
12345678 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
以下示例使用 Max 方法以获取每个联系人 ID 的最大应付款总计。
1234567891011121314151617181920 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
以下示例使用 Max 方法以针对每个联系人 ID 获取具有最大应付款总计的订单。
123456789101112131415161718192021222324252627 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
Min
以下示例使用 Min 方法以获取最小应付款总计。
12345678 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
以下示例使用 Min 方法以获取每个联系人 ID 的最小应付款总计。
1234567891011121314151617181920 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
以下示例使用 Min 方法以针对每个联系人获取具有最小应付款总计的订单。
12345678910111213141516171819202122232425262728 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
Sum
以下示例使用 Sum 方法以获取 SalesOrderDetail 表中订单数量的总数。
12345678 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
以下示例使用 Sum 方法以获取每个联系人 ID 的应付款总计。
12345678910111213141516171819 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
Skip
以下示例使用 Skip<(Of <<'(TSource>)>>) 方法以获取 Contact 表中除前三个联系人之外的所有联系人。
12345678910111213141516 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ // LINQ to Entities only supports Skip on ordered collections. IOrderedQueryable |
以下示例使用 Skip<(Of <<'(TSource>)>>) 方法以获取 Seattle 的前两个地址之外的所有地址。
1234567891011121314151617181920212223242526 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet addresses = AWEntities.Addresses; ObjectSet |
Take
以下示例使用 Take<(Of <<'(TSource>)>>) 方法以只从 Contact 表中获取前五个联系人。
123456789101112131415 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
以下示例使用 Take<(Of <<'(TSource>)>>) 方法以获取 Seattle 的前三个地址。
1234567891011121314151617181920212223 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet addresses = AWEntities.Addresses; ObjectSet |
ToArray
下面的示例使用 ToArray<(Of <<'(TSource>)>>) 方法立即将序列计算为数组。
123456789101112131415 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
ToDictionary
以下示例使用 ToDictionary 方法以立即将序列和相关的键表达式转换为字典。
12345678910 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
ToList
以下示例使用 ToList<(Of <<'(TSource>)>>) 方法以立即将序列转换为 List<(Of <(<'T>)>)>,其中,T 属于类型 DataRow。
123456789101112131415 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
GroupJoin
以下示例针对 SalesOrderHeader 表和 SalesOrderDetail 表执行 GroupJoin 以查找每个客户的订单数。 组联接等效于左外部联接,它返回第一个(左侧)数据源的每个元素(即使其他数据源中没有关联元素)。
12345678910111213141516171819202122 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
下面的示例对 Contact 和 SalesOrderHeader 表执行 GroupJoin 以查找每个联系人的订单数。 将显示每个联系人的订单数和 ID。
1234567891011121314151617181920212223242526 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
Join
以下示例针对 Contact 表和 SalesOrderHeader 表执行联接。
123456789101112131415161718192021222324252627282930313233 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
以下示例针对 Contact 表和 SalesOrderHeader 表执行联接,同时按联系人 ID 对结果分组。
123456789101112131415161718192021222324252627282930313233343536 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
First
以下示例使用 First 方法查找以“caroline”开头的第一个电子邮件地址。
12345678910 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |
GroupBy
下面的示例使用 GroupBy 方法来返回按邮政编码分组的 Address 对象。 这些结果将投影到一个匿名类型。
12345678910111213141516 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ var query = AWEntities.Addresses .GroupBy( address => address.PostalCode) .Select( address => address); foreach (IGrouping |
下面的示例使用 GroupBy 方法来返回按联系人姓氏的首字母分组的 Contact 对象。 这些结果还按姓氏的首字母进行排序,并投影到一个匿名类型。
123456789101112131415161718 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ var query = AWEntities.Contacts .GroupBy(c => c.LastName.Substring(0,1)) .OrderBy(c => c.Key) .Select(c => c); foreach (IGrouping |
下面的示例使用 GroupBy 方法来返回按客户 ID 分组的 SalesOrderHeader 对象。 同时还返回每个客户的销售数量。
1234567891011121314151617 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ var query = AWEntities.SalesOrderHeaders .GroupBy(order => order.CustomerID); foreach (IGrouping |
导航关系
实体框架中的导航属性是快捷方式属性,用于定位位于关联各端的实体。导航属性允许用户通过关联集从一个实体导航到另一个实体或从一个实体导航到多个相关的实体。
以下示例采用基于方法的查询语法,使用 SelectMany 方法以获取其姓氏为“Zhou”的联系人的所有订单。 Contact.SalesOrderHeader 导航属性用于获取每个联系人的 SalesOrderHeader 对象的集合。
123456789101112 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ IQueryable |
采用基于方法的查询语法的以下示例使用 Select 方法以获取所有联系人 ID 和姓氏为“Zhou”的每个联系人的应付款总计。 Contact.SalesOrderHeader 导航属性用于获取每个联系人的 SalesOrderHeader 对象的集合。 Sum 方法使用 Contact.SalesOrderHeader 导航属性以汇总每个联系人的所有订单的应付款总计。
12345678910111213141516 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ var ordersQuery = AWEntities.Contacts .Where(c => c.LastName == "Zhou") .Select(c => new { ContactID = c.ContactID, Total = c.SalesOrderHeaders.Sum(o => o.TotalDue) }); foreach (var contact in ordersQuery) { Console.WriteLine("Contact ID: {0} Orders total: {1}", contact.ContactID, contact.Total); }} |
采用基于方法的查询语法的以下示例获取其姓氏为“Zhou”的联系人的所有订单。 Contact.SalesOrderHeader 导航属性用于获取每个联系人的 SalesOrderHeader 对象的集合。 联系人的姓名和订单以匿名类型返回。
1234567891011121314151617 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ var ordersQuery = AWEntities.Contacts .Where(c => c.LastName == "Zhou") .Select(c => new { LastName = c.LastName, Orders = c.SalesOrderHeaders }); foreach (var order in ordersQuery) { Console.WriteLine("Name: {0}", order.LastName); foreach (SalesOrderHeader orderInfo in order.Orders) { Console.WriteLine("Order ID: {0}, Order date: {1}, Total Due: {2}", orderInfo.SalesOrderID, orderInfo.OrderDate, orderInfo.TotalDue); } Console.WriteLine(""); }} |
以下示例使用 SalesOrderHeader.Address 和 SalesOrderHeader.Contact 导航属性以获取与每个订单关联的 Address 对象和 Contact 对象的集合。 Seattle 城市发生的每个订单的联系人姓氏、街道地址、销售订单号和应付款总计将以匿名类型返回。
1234567891011121314151617181920212223 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ var ordersQuery = AWEntities.SalesOrderHeaders .Where(o => o.Address.City == "Seattle") .Select(o => new { ContactLastName = o.Contact.LastName, ContactFirstName = o.Contact.FirstName, StreetAddress = o.Address.AddressLine1, OrderNumber = o.SalesOrderNumber, TotalDue = o.TotalDue }); foreach (var orderInfo in ordersQuery) { Console.WriteLine("Name: {0}, {1}", orderInfo.ContactLastName, orderInfo.ContactFirstName); Console.WriteLine("Street address: {0}", orderInfo.StreetAddress); Console.WriteLine("Order number: {0}", orderInfo.OrderNumber); Console.WriteLine("Total Due: {0}", orderInfo.TotalDue); Console.WriteLine(""); }} |
以下示例使用 Where 方法以查找在 2003 年 12 月 1 日之后生成的订单,然后使用 order.SalesOrderDetail 导航属性以获取每个订单的详细信息。
12345678910111213141516171819202122 | using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){ ObjectSet |