65.9K
CodeProject 正在变化。 阅读更多。
Home

LINQ 从基础到高级 - MVC演示应用程序

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.91/5 (12投票s)

2017年5月14日

MIT

5分钟阅读

viewsIcon

21488

在这里,在本文中,我们将看到一些 LINQ 查询,涵盖基础和高级部分。

引言

在这里,在本文中,我们将看到一些 LINQ 查询,涵盖基础和高级部分。LINQ 查询是在几年前引入的,旨在为跨许多数据源和格式处理数据提供一致的方式。在 LINQ 查询中,您将始终处理对象,这使得编写查询非常简单。我希望您已经编写了很多 LINQ 查询,如果您还没有,我强烈建议您阅读这篇博文,您可以在其中找到“我们为什么需要使用 LINQ?”的答案。在这里,我将创建一个 MVC 演示应用程序。我希望您会喜欢。现在让我们开始吧。

背景

每当我能用 C# 编写一些服务器端代码时,我总是用 LINQ 来写。几周前,我被分配到一个培训项目,我的任务是教授 LINQ,因此本文涵盖了我为该培训项目编写的查询。希望您觉得有用。

Using the Code

LINQ 查询可以有两种写法

  • 查询语法
  • 方法链或使用点(.)运算符

互联网上有很多关于 LINQ 的文章,但大多数都没有涵盖以两种可能方式编写查询的区别,本文的目的是以两种方式编写查询,以便您可以理解它们之间的差异。

正如我所提到的,我们将创建一个 MVC 应用程序,我们需要先创建它,然后配置实体。让我们去吧。

创建数据库

首先,我们需要配置我们的数据库。为此,您可以从这里下载 Wild World Importers,或者您可以运行上面下载链接中包含的脚本文件。

创建数据库后,您就可以在其中创建您的 MVC 应用程序和实体数据模型。

将 MVC 应用程序与实体数据模型配置在一起

此时,我希望您已经将 MVC 应用程序与实体数据模型配置在一起。现在是时候创建一个控制器和实体对象了。

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Windows.Forms;
using LINQ_B_to_A.Models;
namespace LINQ_B_to_A.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        public MyDataModel DtContext { get; set; } = new MyDataModel();
    }
}

现在我们可以编写一些 LINQ 查询了,因为一切都已准备就绪。

使用可能的 Action 设置 Index 视图

这只是为了调用我们将要编写的 Action。让我们看看 Index 页面。

@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
<input type="button" class="btn-info" 
onclick="location.href='@Url.Action
("LoadAll","Home")'" value="Load All - Query Expression"/>
<input type="button" class="btn-info" onclick="location.href='@Url.Action
("JoinWithWhere","Home")'" value="Join With Where" />
<input type="button" class="btn-info" onclick="location.href='@Url.Action
("LeftJoin","Home")'" value="Left Join" />
<input type="button" class="btn-info" onclick="location.href='@Url.Action
("DistinctSample","Home")'" value="Distinct Sample" />
<input type="button" class="btn-info" onclick="location.href='@Url.Action
("EqualsSamples","Home")'" value="Equals Sample" />
<input type="button" class="btn-info" onclick="location.href='@Url.Action
("NotEqualsSamples","Home")'" value="Not Equals" />
<input type="button" class="btn-info" onclick="location.href='@Url.Action
("PagingQueries","Home")'" value="Paging Queries" />
<input type="button" class="btn-info" onclick="location.href='@Url.Action
("MathQueries","Home")'" value="Math Queries" />
<input type="button" class="btn-info" onclick="location.href='@Url.Action
("StringQueries","Home")'" value="String Queries" />
<input type="button" class="btn-info" onclick="location.href='@Url.Action
("SelectMany","Home")'" value="Select Many" />

带有 StartWith 和 Take 的普通 Select 查询

让我们看一下下面的查询

/// <summary>
/// Linq query with Select
/// </summary>
/// <returns></returns>
public ActionResult LoadAll()
{
    var loadAllData = (from d in DtContext.Cities 
    where d.CityName.StartsWith("C") select d).Take(10);
    //Method Chain Format
    var loadAllData1 = DtContext.Cities.Where
    (d => d.CityName.StartsWith("C")).Take(10);
    return PartialView(loadAllData);
}

正如您所看到的,我们只是以两种方式从Cities获取数据。我们使用StartWith作为过滤器,它实际上查找以字母C开头的城市名称,最后我们从中提取 10 个元素。第一个查询是“查询语法”,第二个是“方法链”。我个人比较喜欢第二种方式。您呢?

@model IQueryable<LINQ_B_to_A.Models.City>
<style>
    dd, dt, pre {
        border: 1px solid #ccc;
        padding: 5px;
        margin: 5px;
        width: auto;
        width: 20%;
    }

    dd {
        background-color: #a9a9a9
    }
    pre {
        width: auto;
    }
</style>
<dd>City Names</dd>
@foreach (var ctyObj in Model)
{
    <dt>@ctyObj.CityName</dt>
}
<pre>
       public ActionResult LoadAll()
        {
            var loadAllData = (from d in DtContext.Cities where d.CityName.StartsWith("C") select d).Take(10);
            //Method Chain Format
            var loadAllData1 = DtContext.Cities.Where(d => d.CityName.StartsWith("C")).Take(10);
            return PartialView(loadAllData);
        }
</pre>

我们现在准备好看到第一个查询的实际运行效果了。

JOIN 查询

要编写join,查询将如下所示

/// <summary>
        /// Linq query with join and where
        /// </summary>
        /// <returns></returns>
        public ActionResult JoinWithWhere()
        {
            var loadAllData = (from oOrders in DtContext.Orders
                               join oOrderLines in DtContext.OrderLines
                               on oOrders.OrderID equals oOrderLines.OrderID
                               orderby oOrders.OrderID
                               select new OrderAndOrderLines()
                               {
                                   OrderId = oOrders.OrderID,
                                   Description = oOrderLines.Description,
                                   Quantity = oOrderLines.Quantity
                               }).Take(10);
            //Method Chain Format
            var asMethodChain = DtContext.Orders.Join
            (DtContext.OrderLines, oOrders => oOrders.OrderID,
                    oOrderLines => oOrderLines.OrderID,
                    (oOrders, oOrderLines) => new { oOrders, oOrderLines })
                .OrderBy(@o => @o.oOrders.OrderID)
                .Select(@s => new OrderAndOrderLines()
                {
                    OrderId = @s.oOrders.OrderID,
                    Description = @s.oOrderLines.Description,
                    Quantity = @s.oOrderLines.Quantity
                }).Take(10);
            return PartialView(loadAllData);
        }

在上面的查询中,我们只是使用OrderID连接OrderOrderLines表,并使用另一个自定义模型OrderAndOrderLines进行select

namespace LINQ_B_to_A.Models
{
    public partial class OrderAndOrderLines
    {
        public int OrderId { get; set; }
        public string Description { get; set; }
        public int? Quantity { get; set; }
    }
}

视图可以这样编写

@model IEnumerable<LINQ_B_to_A.Models.OrderAndOrderLines>
<style>
    td, th, thead,pre {
        border: 1px solid #ccc;
        padding: 5px;
        margin: 5px;
        width: auto;
        width: 20%;
    }
    caption {
        background-color: #a9a9a9
    }
    pre {
        width: auto;
    }
</style>
<table>
    <caption>Order Details</caption>
    <tr>
        <th>Order ID</th>
        <th>Description</th>
        <th>Quantity</th>
    </tr>
    @foreach (var @item in Model)
    {
        <tr>
            <td>@item.OrderId</td>
            <td>@item.Description</td>
            <td>@item.Quantity</td>
        </tr>
    }
</table>
<pre>
     public ActionResult JoinWithWhere()
        {
            var loadAllData = (from oOrders in DtContext.Orders
                               join oOrderLines in DtContext.OrderLines
                               on oOrders.OrderID equals oOrderLines.OrderID
                               orderby oOrders.OrderID
                               select new OrderAndOrderLines()
                               {
                                   OrderId = oOrders.OrderID,
                                   Description = oOrderLines.Description,
                                   Quantity = oOrderLines.Quantity
                               }).Take(10);
            //Method Chain Format
            var asMethodChain = DtContext.Orders.Join
            (DtContext.OrderLines, oOrders => oOrders.OrderID,
                    oOrderLines => oOrderLines.OrderID,
                    (oOrders, oOrderLines) => new { oOrders, oOrderLines })
                .OrderBy(o => o.oOrders.OrderID)
                .Select(s => new OrderAndOrderLines()
                {
                    OrderId = s.oOrders.OrderID,
                    Description = s.oOrderLines.Description,
                    Quantity = s.oOrderLines.Quantity
                }).Take(10);
            return PartialView(loadAllData);
        }
</pre>

运行 Action 后,您可以看到结果如下

左连接 (Left JOIN) 查询

要编写Left join,查询将如下所示

/// <summary>
        /// Linq query with Left Join
        /// </summary>
        /// <returns></returns>
        public ActionResult LeftJoin()
        {
            var loadAllData = (from oOrder in DtContext.Orders
                               join oOrderLine in DtContext.OrderLines
                               on oOrder.OrderID equals oOrderLine.OrderID
                               into lftOrder
                               from afterJoined in lftOrder.DefaultIfEmpty()
                               orderby oOrder.OrderID descending
                               select new OrderAndOrderLines()
                               {
                                   OrderId = oOrder.OrderID,
                                   Description = afterJoined.Description
                               }).Take(10).ToList();
            //Method Chain Format
            var lftJoinMethodChain = (DtContext.Orders.GroupJoin(DtContext.OrderLines,
                    oOrder => oOrder.OrderID, oOrderLine => oOrderLine.OrderID,
                    (oOrder, lftJoin) => new { oOrder, lftJoin })
                .SelectMany(@sm => @sm.lftJoin.DefaultIfEmpty(), 
                (@sm, afterJoin) => new { @sm, afterJoin })
                .OrderByDescending(@o => @o.sm.oOrder.OrderID)
                .Select(@s => new OrderAndOrderLines()
                {
                    OrderId = @s.sm.oOrder.OrderID,
                    Description = @s.afterJoin.Description
                })).Take(10).ToList();
            return PartialView(loadAllData);
        }

在上面的查询中,我们只是使用OrderID连接OrderOrderLines表,并使用另一个自定义模型OrderAndOrderLines进行select,与我们之前的查询一样。您可以找到的差异是,使用了'into'和'DefaultIfEmpty'语句。DefaultIfEmpty确保在第二张表中找不到相应的行时返回空。

视图可以这样编写

@model IEnumerable<LINQ_B_to_A.Models.OrderAndOrderLines>
<style>
    td, th, thead, pre {
        border: 1px solid #ccc;
        padding: 5px;
        margin: 5px;
        width: auto;
        width: 20%;
    }
    caption {
        background-color: #a9a9a9
    }
    pre {
        width: auto;
    }
</style>
<table>
    <caption>Order Details</caption>
    <tr>
        <th>Order ID</th>
        <th>Description</th>
        <th>Quantity</th>
    </tr>
    @foreach (var @item in Model)
    {
        <tr>
            <td>@item.OrderId</td>
            <td>@item.Description</td>
            <td>@item.Quantity</td>
        </tr>
    }
</table>
<pre>
    public ActionResult LeftJoin()
        {
            var loadAllData = (from oOrder in DtContext.Orders
                               join oOrderLine in DtContext.OrderLines
                               on oOrder.OrderID equals oOrderLine.OrderID
                               into lftOrder
                               from afterJoined in lftOrder.DefaultIfEmpty()
                               orderby oOrder.OrderID descending
                               select new OrderAndOrderLines()
                               {
                                   OrderId = oOrder.OrderID,
                                   Description = afterJoined.Description
                               }).Take(10).ToList();
            //Method Chain Format
            var lftJoinMethodChain = (DtContext.Orders.GroupJoin(DtContext.OrderLines,
                    oOrder => oOrder.OrderID, oOrderLine => oOrderLine.OrderID,
                    (oOrder, lftJoin) => new { oOrder, lftJoin })
                .SelectMany(sm => sm.lftJoin.DefaultIfEmpty(), 
                (sm, afterJoin) => new { sm, afterJoin })
                .OrderByDescending(o => o.sm.oOrder.OrderID)
                .Select(s => new OrderAndOrderLines()
                {
                    OrderId = s.sm.oOrder.OrderID,
                    Description = s.afterJoin.Description
                })).Take(10).ToList();
            return PartialView(loadAllData);
        }

运行 Action 后,您可以看到结果如下

正如您在图中看到的,订单 ID 200000 在第二张表中没有对应的行,因此显示为空。

Distinct 查询

下面的查询显示了如何编写一个简单的 Distinct 查询。

/// <summary>
        /// Linq query Distinct sample
        /// </summary>
        /// <returns></returns>
        public ActionResult DistinctSample()
        {
            var distictSample = (from oOrder in DtContext.OrderLines
                                 select oOrder.Description).Distinct().Take(10).ToList();
            //Method Chain Format
            var distictAsMethodChain = (DtContext.OrderLines.Select
            (oOrder => oOrder.Description)).Distinct().Take(10).ToList();
            return PartialView(distictSample);
        }

在上面的查询中,我们使用Distinct来确保只从结果中选择不重复的项。视图可以这样编写

@model  List<string>
<style>
    dd, dt, pre {
        border: 1px solid #ccc;
        padding: 5px;
        margin: 5px;
        width: auto;
        width: 20%;
    }
    dd {
        background-color: #a9a9a9
    }
    pre {
        width: auto;
    }
</style>
<dd>Order Descriptions</dd>
@foreach (var orderLinesyObj in Model)
{
    <dt>@orderLinesyObj</dt>
}
<pre>
    public ActionResult DistinctSample()
        {
            var distictSample = (from oOrder in DtContext.OrderLines
                                 select oOrder.Description).Distinct().Take(10).ToList();
            //Method Chain Format
            var distictAsMethodChain = 
            (DtContext.OrderLines.Select
            (oOrder => oOrder.Description)).Distinct().Take(10).ToList();
            return PartialView(distictSample);
        }
</pre>

运行 Action 后,您可以看到结果如下

Equals 和 Not Equals 查询

我们可以按如下方式编写 equals 和 not equals 查询

/// <summary>
        /// Linq query Equals sample
        /// </summary>
        /// <returns></returns>
        public ActionResult EqualsSamples()
        {
            var objEquals = (from objCity in DtContext.Cities
                             where objCity.CityName.Equals("Troy")
                             select objCity).Take(2);
            //Method Chain Format
            var objEquals1 = DtContext.Cities.Where
            (d => d.CityName.Equals("Troy")).Take(2);
            return PartialView("OperatorSamples", objEquals);
        }
        /// <summary>
        /// Linq query Not Equals sample
        /// </summary>
        /// <returns></returns>
        public ActionResult NotEqualsSamples()
        {
            var objNotEquals = (from objCity in DtContext.Cities
                                where objCity.CityName != "Troy"
                                select objCity).Take(5);
            var objNotEquals1 = (from objCity in DtContext.Cities
                                 where !objCity.CityName.Equals("Troy")
                                 select objCity).Take(5);
            //Method Chain Format
            var objNotEquals2 = DtContext.Cities.Where
            (d => d.CityName != "Troy").Take(2);
            var objNotEquals3 = DtContext.Cities.Where
            (d => !d.CityName.Equals("Troy")).Take(2);
            return PartialView("OperatorSamples", objNotEquals);
        }

视图可以这样编写

@model IQueryable<LINQ_B_to_A.Models.City>
<style>
    td, th, thead, pre {
        border: 1px solid #ccc;
        padding: 5px;
        margin: 5px;
        width: auto;
        width: 20%;
    }
    caption {
        background-color: #a9a9a9
    }
    pre {
        width: auto;
    }
</style>
    <table>
        <caption>City Details</caption>
        <tr>
            <th>City ID</th>
            <th>City Name</th>
            <th>City Location</th>
        </tr>
@foreach (var @item in Model)
{
    <tr>
    <td>@item.CityID</td>
    <td>@item.CityName</td>
    <td>@item.Location</td>
    </tr>
}
</table>
<caption>Equals Oerator</caption>
<pre>
    public ActionResult EqualsSamples()
        {
            var objEquals = (from objCity in DtContext.Cities
                                       where objCity.CityName.Equals("Troy")
                                       select objCity).Take(2);
            //Method Chain Format
            var objEquals1 = DtContext.Cities.Where
            (d => d.CityName.Equals("Troy")).Take(2);           
            return PartialView("OperatorSamples", objEquals);
        }
        public ActionResult NotEqualsSamples()
        {
            var objNotEquals = (from objCity in DtContext.Cities
                where objCity.CityName != "Troy"
                select objCity).Take(5);
            var objNotEquals1 = (from objCity in DtContext.Cities
                where !objCity.CityName.Equals("Troy")
                select objCity).Take(5);
            //Method Chain Format
            var objNotEquals2 = DtContext.Cities.Where
            (d => d.CityName != "Troy").Take(2);
            var objNotEquals3 = DtContext.Cities.Where
            (d => !d.CityName.Equals("Troy")).Take(2);
            return PartialView("OperatorSamples", objNotEquals);
        }    
        public ActionResult PagingQueries()
        {
            var objNotEquals = (from objCity in DtContext.Cities
                where objCity.CityName != "Troy"
                orderby objCity.CityName ascending
                select objCity).Skip(5).Take(5);
            //Method Chain Format
            var objNotEquals2 = DtContext.Cities.Where
            (d => d.CityName != "Troy").Skip(5).Take(5);
            return PartialView("OperatorSamples", objNotEquals);
        }

运行 Action 后,您可以看到结果如下

LINQ 分页查询

分页查询始终很重要,因为我们在一些网格控件中使用它们,使用 LINQ,它们非常容易。让我们看其中一个查询。

/// <summary>
        /// Linq Paging Queries
        /// </summary>
        /// <returns></returns>
        public ActionResult PagingQueries()
        {
            var objNotEquals = (from objCity in DtContext.Cities
                                where objCity.CityName != "Troy"
                                orderby objCity.CityName ascending
                                select objCity).Skip(5).Take(5);
            //Method Chain Format
            var objNotEquals2 = DtContext.Cities.Where
            (d => d.CityName != "Troy").Skip(5).Take(5);
            return PartialView("OperatorSamples", objNotEquals);
        }

运行 Action 后,您可以看到结果如下

LINQ 数学查询

在这里,我们将编写 LINQ 查询中可能的Math函数。

/// <summary>
        /// Math Queries
        /// </summary>
        /// <returns></returns>
        public ActionResult MathQueries()
        {
            var objMath = (from objInv in DtContext.InvoiceLines
                           where objInv.ExtendedPrice > 
                           10 && objInv.Quantity < 15
                           orderby objInv.InvoiceLineID descending
                           select new MathClass()
                           {
                               Actual = objInv.ExtendedPrice,
                               Round = Math.Round(objInv.ExtendedPrice),
                               Floor = Math.Floor(objInv.ExtendedPrice),
                               Ceiling = Math.Ceiling(objInv.ExtendedPrice),
                               Abs = Math.Abs(objInv.ExtendedPrice)
                           }).Take(10);
            //Method Chain Format
            var objMath2 = DtContext.InvoiceLines
                .Where(objInv => objInv.ExtendedPrice > 
                10 && objInv.Quantity < 15)
                .OrderByDescending(o => o.InvoiceLineID)
                .Select(objInv => new MathClass()
                {
                    Actual = objInv.ExtendedPrice,
                    Round = Math.Round(objInv.ExtendedPrice),
                    Floor = Math.Floor(objInv.ExtendedPrice),
                    Ceiling = Math.Ceiling(objInv.ExtendedPrice),
                    Abs = Math.Abs(objInv.ExtendedPrice)
                }).Take(10);
            return PartialView("MathQueries", objMath);
        }

正如您所看到的,我们在查询中编写了大多数可能的Math函数,并使用自定义模型MathClass进行选择。

namespace LINQ_B_to_A.Models
{
    public partial class MathClass
    {
        public decimal Actual { get; set; }
        public decimal Round { get; set; }
        public decimal Floor { get; set; }
        public decimal Ceiling { get; set; }
        public decimal Abs { get; set; }
    }
}

现在让我们看看视图。

@model IQueryable<LINQ_B_to_A.Models.MathClass>
<style>
    td, th, thead, pre {
        border: 1px solid #ccc;
        padding: 5px;
        margin: 5px;
        width: auto;
        width: 20%;
    }
    caption {
        background-color: #a9a9a9
    }
    pre {
        width: auto;
    }
</style>
<table>
    <caption>Math Operators</caption>
    <tr>     
    </tr>
    @foreach (var @item in Model)
    {
        <tr>
            <td>Actual: @item.Actual</td>
            <td>Round: @item.Round</td>
            <td>Floor: @item.Floor</td>
            <td>Ceiling: @item.Ceiling</td>
            <td>Abs: @item.Abs</td>
        </tr>
    }
</table>
<pre>
    public ActionResult MathQueries()
        {
            var objMath = (from objInv in DtContext.InvoiceLines
                          where objInv.ExtendedPrice > 10 
                          && objInv.Quantity < 15
                          orderby objInv.InvoiceLineID descending
                          select new MathClass()
                          {
                              Actual = objInv.ExtendedPrice,
                              Round = Math.Round(objInv.ExtendedPrice),
                              Floor = Math.Floor(objInv.ExtendedPrice),
                              Ceiling = Math.Ceiling(objInv.ExtendedPrice),
                              Abs = Math.Abs(objInv.ExtendedPrice)
                          }).Take(10);
            //Method Chain Format
            var objMath2 = DtContext.InvoiceLines
                .Where(objInv => objInv.ExtendedPrice > 10 
                && objInv.Quantity < 15)
                .OrderByDescending(o => o.InvoiceLineID)
                .Select(objInv => new MathClass()
                {
                    Actual = objInv.ExtendedPrice,
                    Round = Math.Round(objInv.ExtendedPrice),
                    Floor = Math.Floor(objInv.ExtendedPrice),
                    Ceiling = Math.Ceiling(objInv.ExtendedPrice),
                    Abs = Math.Abs(objInv.ExtendedPrice)
                }).Take(10);
            return PartialView("MathQueries", objMath);
        }
</pre>

现在看看结果。

LINQ 字符串查询

正如我们看到Math查询一样,在这里我们将编写 LINQ 查询中可能的String函数。

/// <summary>
        /// String Queries
        /// </summary>
        /// <returns></returns>
        public ActionResult StringQueries()
        {
            var objString = (from objInv in DtContext.InvoiceLines
                             where objInv.ExtendedPrice > 10 
                             && objInv.Quantity < 15
                             orderby objInv.InvoiceLineID descending
                             select new StringClass()
                             {
                                 Actual = objInv.Description,
                                 Insert = objInv.Description.Insert(2, "SibeeshPassion"),
                                 Remove = objInv.Description.Remove(1, 1),
                                 Substring = objInv.Description.Substring(2, 3),
                                 ToLower = objInv.Description.ToLower(),
                                 ToUpper = objInv.Description.ToUpper(),
                                 TrimEnd = objInv.Description.TrimEnd(),
                                 TrimStart = objInv.Description.TrimStart()
                             }).Take(2);
          //Method Chain Format
            var objString2 = DtContext.InvoiceLines
                .Where(objInv => objInv.ExtendedPrice > 10 
                && objInv.Quantity < 15)
                .OrderByDescending(o => o.InvoiceLineID)
                .Select(objInv => new StringClass()
                {
                    Actual = objInv.Description,
                    Insert = objInv.Description.Insert(2, "SibeeshPassion"),
                    Remove = objInv.Description.Remove(1, 1),
                    Substring = objInv.Description.Substring(2, 3),
                    ToLower = objInv.Description.ToLower(),
                    ToUpper = objInv.Description.ToUpper(),
                    TrimEnd = objInv.Description.TrimEnd(),
                    TrimStart = objInv.Description.TrimStart()
                }).Take(2);
            return PartialView("StringQueries", objString);
        }

正如您所看到的,这里我们使用的是自定义模型StringClass

namespace LINQ_B_to_A.Models
{
    public partial class StringClass
    {
        public string Actual { get; set; }
        public string Insert { get; set; }
        public string Remove { get; set; }
        public string Substring { get; set; }
        public string ToUpper { get; set; }
        public string ToLower { get; set; }
        public string TrimStart { get; set; }
        public string TrimEnd { get; set; }
    }
}

现在让我们看看视图。

@model IQueryable<LINQ_B_to_A.Models.StringClass>
<style>
    td, th, thead, pre {
        border: 1px solid #ccc;
        padding: 5px;
        margin: 5px;
        width: auto;
        width: 20%;
    }
    caption {
        background-color: #a9a9a9
    }
    pre {
        width: auto;
    }
</style>
<table>
    <caption>String Operators</caption>
    <tr>     
    </tr>
    @foreach (var @item in Model)
    {
        <tr>
            <td>Actual: @item.Actual</td>
            <td>Insert: @item.Insert</td>
            <td>Remove: @item.Remove</td>
            <td>Substring: @item.Substring</td>
            <td>ToLower: @item.ToLower</td>
            <td>ToUpper: @item.ToUpper</td>
            <td>TrimEnd: @item.TrimEnd</td>
            <td>TrimStart: @item.TrimStart</td>
        </tr>
    }
</table>
<pre>
        public ActionResult StringQueries()
        {
            var objString = (from objInv in DtContext.InvoiceLines
                where objInv.ExtendedPrice > 10 && objInv.Quantity < 15
                orderby objInv.InvoiceLineID descending
                select new StringClass()
                {
                    Actual = objInv.Description,
                    Insert = objInv.Description.Insert(2,"SibeeshPassion"),
                    Remove = objInv.Description.Remove(1,1),
                    Substring = objInv.Description.Substring(2,3),
                    ToLower = objInv.Description.ToLower(),
                    ToUpper = objInv.Description.ToUpper(),
                    TrimEnd = objInv.Description.TrimEnd(),
                    TrimStart = objInv.Description.TrimStart()
                }).Take(2);
            //Method Chain Format
            var objString2 = DtContext.InvoiceLines
                .Where(objInv => objInv.ExtendedPrice > 10 && objInv.Quantity < 15)
                .OrderByDescending(o => o.InvoiceLineID)
                .Select(objInv => new StringClass()
                {
                    Actual = objInv.Description,
                    Insert = objInv.Description.Insert(2, "SibeeshPassion"),
                    Remove = objInv.Description.Remove(1, 1),
                    Substring = objInv.Description.Substring(2, 3),
                    ToLower = objInv.Description.ToLower(),
                    ToUpper = objInv.Description.ToUpper(),
                    TrimEnd = objInv.Description.TrimEnd(),
                    TrimStart = objInv.Description.TrimStart()
                }).Take(2);
            return PartialView("StringQueries", objString);
        }
</pre>

现在看看结果。

SelectMany 查询

SelectMany查询将结果展平成一维集合,因此要遍历结果,我们只需要一个循环。

如果您使用普通的Select,您将得到一个列表的列表,因此您需要使用两个循环来获取数据。

 /// <summary>
       /// Linq query with SelectMany
        /// </summary>
        /// <returns></returns>
        public ActionResult SelectMany()
        {
            var selectMany = DtContext.Orders.SelectMany(order => order.Invoices).Take(10);
            var select = DtContext.Orders.Select(order => order.Invoices).Take(10);
            return PartialView("SelectMany", selectMany);
        }

现在让我们看看视图。

@model IQueryable<LINQ_B_to_A.Models.Invoice>
<style>
    td, th, thead, pre {
        border: 1px solid #ccc;
        padding: 5px;
        margin: 5px;
        width: auto;
        width: 20%;
    }
    caption {
        background-color: #a9a9a9
    }
    pre {
        width: auto;
    }
</style>
<table>
    <caption>Invoice Details</caption>
    <tr>
        <th>Order ID</th>
        <th>Invoice ID</th>
        <th>Invoice Date</th>
    </tr>
    @foreach (var @item in Model)
    {
        <tr>
            <td>@item.OrderID</td>
            <td>@item.InvoiceID</td>
            <td>@item.InvoiceDate</td>
        </tr>
    }
</table>
<caption>Select Many</caption>
<pre>
     /// <summary>
        /// Linq query with SelectMany
        /// </summary>
        /// <returns></returns>
        public ActionResult SelectMany()
        {
            var selectMany = 
            DtContext.Orders.SelectMany(order => order.Invoices).Take(10);
            var select = DtContext.Orders.Select(order => order.Invoices).Take(10);
            return PartialView("SelectMany", selectMany);
        }
</pre>

现在看看结果。

今天就到这里,下一部分我将带来另一组 LINQ 查询。在此之前,再见。

结论

我是否错过了您认为需要的内容?您觉得这篇文章有用吗?我希望您喜欢这篇文章。请分享您宝贵的建议和反馈。

现在轮到你了。你有什么想法?

请分享您的反馈,但请尽量保持主题。如果您有与本文无关的问题,最好将其发布到 C# Corner、Code Project、Stack Overflow、ASP.NET Forum,而不是在此评论。在 Twitter 或电子邮件中给我发送您问题的链接,如果我能帮上忙,我会尽力帮助。

© . All rights reserved.