SQL Server 如何在ASP.NETMVC中使用LINQ组件?

nzk0hqpo  于 2022-12-17  发布在  .NET
关注(0)|答案(2)|浏览(156)

我有一个数据库:

  • 我需要在我的网站中显示的查询SQL:
strDateStart = Format(Me.ctlNgayBD.Value, "yyyy/MM/dd")
   strDateEnd = Format(Me.ctlNgayKT.Value, "yyyy/MM/dd")
Select Loaive, LoaiXe,
      Count(*) As Tongxe,
      Sum(Phi) As Tongphi,
      phi
  From View_XeQuaTramreport As a  
  Where catruc = " & catruc & " And Convert(varchar(10),NgayCa,111) = '" & strDate & "' 
  Group by Loaive,Loaixe,phi 
  Order by Loaive,Loaixe,phi
Select Loaive, LoaiXe,
       Count(*) As Tongxe,
       Sum(Phi) As Tongphi,
       phi
   From View_XeQuaTramreport As a 
   Where Convert(varchar(10),NgayCa,111) >= '" & strDateStart & "'
   and Convert(varchar(10),NgayCa,111) <= '" & strDateEnd & "'
   Group by Loaive,Loaixe,phi
   Order by Loaive,Loaixe,phi"
  • 图像示例SQL选择:

  • 我的控制器:有没有办法在控制器中使用LINQa来代替字符串SQL查询?
public DongphuocDbContext db = new DongphuocDbContext();
  
  // GET: Report
  public ActionResult Index(DateTime? start, DateTime? end )
  {
      var _context = new DongphuocDbContext();
      string mainconn = ConfigurationManager.ConnectionStrings["DongphuocDbContext"].ConnectionString;
      SqlConnection sqlconn = new SqlConnection(mainconn);
      string sqlquery = "select Loaive,LoaiXe,Count(*) As Tongxe , Sum(Phi) As Tongphi ,Phi" + " from [dbo].[View_XeQuaTramReport] As a  " +"where NgayCa between '" + start + "' and '" + end + "'" + " Group by Loaive,Loaixe,phi" + " Order by Loaive,Loaixe,phi";
  
      SqlCommand sqlcomm = new SqlCommand(sqlquery, sqlconn);
      sqlconn.Open();
      SqlDataAdapter sda = new SqlDataAdapter(sqlcomm);
      DataSet ds = new DataSet();
      sda.Fill(ds);
  
      List<View_XeQuaTramReport> lc = new List<View_XeQuaTramReport>();
  
      foreach (DataRow dr in ds.Tables[0].Rows)
      {
          lc.Add(new View_XeQuaTramReport
          {  
              LoaiVe = Convert.ToByte(dr["LoaiVe"]),
              LoaiXe = Convert.ToByte(dr["LoaiXe"]),
              Phi = Convert.ToDecimal(dr["Phi"])
          });
      }
      sqlconn.Close();
      ModelState.Clear();
      return View(lc);  
  }

我的视图:我想在第一卷视图中显示2个表。并添加Count"Tongxe"Sum"TongPhi",但我不能添加。

<center>
    <p>
        @using (Html.BeginForm("Index", "Report", FormMethod.Get))
        {
            <input type="date" name="start" />
            <input type="date" name="end" />
            <input type="submit" name="submit" value="Search" />
        }
    </p>
    <table class="table">
        <tr>
            <th> @Html.DisplayName("LoaiVe") </th>
            <th> @Html.DisplayName("LoaiXe") </th>
            <th> @Html.DisplayName("Phi") </th>
        </tr>

        @foreach (var item in Model)
        {
    <tr>
        <td> @Html.DisplayFor(modelItem => item.LoaiVe)</td>
        <td> @Html.DisplayFor(modelItem => item.LoaiXe)</td>
        <td> @Html.DisplayFor(modelItem => item.Phi)</td>

    </tr>
        }
    </table>
</center>

以下是DongphuocDbContext的型号配置:

modelBuilder.Entity<View_XeQuaTramReport>()
            .Property(e => e.Phi)
            .HasPrecision(19, 4); 
modelBuilder.Entity<View_XeQuaTramReport>()
            .Property(e => e.MSNV)
            .IsUnicode(false); 
modelBuilder.Entity<View_XeQuaTramReport>()
            .Property(e => e.maNhanVien)
            .IsUnicode(false); 
modelBuilder.Entity<View_XeQuaTramReport>()
            .Property(e => e.ID)
            .IsUnicode(false);

1.我需要帮助更改字符串SQL查询-〉LINQ
1.我需要添加Count"Tongxe"sum"TongPhi"

j9per5c4

j9per5c41#

DongphuocDbContext中查看是否已经定义了View_XeQuaTramReport集合。如果已经定义了,下面的代码可以满足您的需要:

DateTime start = ...
DateTime end = ...

var Result = _context.View_XeQuaTramReport
    .Where(item => item.NgayCa >= start && item.NgayCa <= end) // Date arithmetic, not text
    .GroupBy(item => new {item.Loaive, item.Loaixe, item.Phi}) // Multi-value key
    .Select(grp => new {
        Loaive = grp.Key.Loaive,
        Loaixe = grp.Key.Loaixe,
        Tongxe = grp.Count(),
        Tongphi = grp.Sum(item => item.Phi),
        Phi = grp.Key.Phi
    })
    .ToList();

关于原始查询的附注:切勿通过将日期转换为文本来进行日期比较(如Convert(varchar(10),NgayCa,111))。相反,学习如何参数化查询,将startend作为正确的DATE/DATETIME/DATETIME2类型传入,并执行直接的日期到日期比较。这对于数据库效率至关重要,因为如果您有NgayCa上的索引(您可能应该这样做),如果您进行字符串比较而不是日期比较,这个索引将变得毫无用处。

huwehgph

huwehgph2#

这看起来像SQL Server,图像中的日期值看起来像datetime值。没有理由将日期转换为字符串,即使是从日期选择器控件。事实上,当前SQL查询的运行速度远远低于预期,甚至可能由于字符串转换而返回错误的结果。
SQL查询应如下所示,使用日期类型的参数@from和@to

Select Loaive, LoaiXe,
       Count(*) As Tongxe,
       Sum(Phi) As Tongphi,
       phi
   From View_XeQuaTramreport As a 
   Where NgayCa between @from and @to
   Group by Loaive,Loaixe,phi
   Order by Loaive,Loaixe,phi

EF Core允许使用LINQ创建等效查询:

public ActionResult Index(DateTime start, DateTime end )
{
  using (var context = new DongphuocDbContext())
  {
      var results=context.View_XeQuaTramReport
                         .AsNoTracking()
                         .Where(r=>r.NgayCa >= start.Date && 
                                   r.NgayCa < end.Date.AddDays(1))
                         .GroupBy(r=>new{r.Loaive,r.Loaixe,r.phi})
                         .Select(g=>new View_XeQuaTramReport
                          {  
                              LoaiVe = g.Key.LoaiVe,
                              LoaiXe = g.Key.LoaiXe,
                              Phi = g.Key.Phi,
                              Tongxe = g.Key.Count(),
                              Tongphi = g.Sum(r=>r.Phi)
                          })
                          .OrderBy(r=>new {r.Loaive,r.Loaixe,r.Phi})
                          .ToList();
      return View(results);  
  }
}

LINQ没有Between子句。如果数据库字段包含时间组件,日期比较也很棘手。此查询中的Where子句将返回日期值大于或等于start日期的所有行(start.Date)和 * 严格小于end之后的第二天 *(end.Date.AddDays(1))。这样,如果r.NgayCa有日期组件,就没有理由从其日期组件中删除它:

.Where(r=>r.NgayCa >= start.Date && r.NgayCa < end.Date.AddDays(1))

AsNoTracking()用于告诉EF * 不 * 跟踪它加载的实体。通常EF会跟踪它加载的所有实体,以便在调用SaveChanges时检测任何更改并生成修改SQL语句。这会占用更多内存并降低查询速度。
最后,DbContext在using块中定义,以确保在不再需要时将其释放。否则,DbContext * 和 * 其跟踪的实体将保留在内存中,直到垃圾收集器运行。

条件查询

问题的操作使用了可为空的日期。只有当我们希望相同的操作在日期之前、之后或之间搜索时,这才有意义。在这种情况下,SQL和LINQ查询都必须重写。这些查询都不适用于NULL日期:x一米十一氮一x、x一米十二氮一x或x一米十三氮一x。
在LINQ中,可以动态构建查询:

public ActionResult Index(DateTime? start, DateTime end )
{

    var query=context.View_XeQuaTramReport
                     .AsNoTracking()
                     .AsQueryable();
if(startDate.HasValue)
{
    query=query.Where(r=>r.NgayCa >= start.Value.Date);
}
if(endDate.HasValue)
{
    query=query.Where(r=>r.NgayCa < end.Value.Date.AddDays(1));
}
var results=query.GroupBy(r=>new{r.Loaive,r.Loaixe,r.phi})
                 .Select(g=>new View_XeQuaTramReport {  
                         LoaiVe = g.Key.LoaiVe,
                         LoaiXe = g.Key.LoaiXe,
                         Phi = g.Key.Phi,
                         Tongxe = g.Key.Count(),
                         Tongphi = g.Sum(r=>r.Phi)
                  })
                  .OrderBy(r=>new {r.Loaive,r.Loaixe,r.Phi})
                  .ToList();

相关问题