使用Lambda表达式查询SQL语句填充的DataTable
Posted
技术标签:
【中文标题】使用Lambda表达式查询SQL语句填充的DataTable【英文标题】:Using Lambda expressions to query DataTable filled by SQL statement 【发布时间】:2019-12-08 11:21:27 【问题描述】:我正在构建一个 WinForm,它在 DataGridView 中显示每个客户的约会次数。我可以使用基本的 SELECT 语句来做到这一点,但要求至少需要 2 个 Lambda 表达式。我创建了 1 个 Lambda 表达式,但到目前为止它什么也没做。据我了解,Lambda 可用于查询 DataTable,类似于 SQL 语句查询表的方式。但由于某种原因,什么都没有发生。 DataTable 填得很好,但 Lambda 什么也没做。
这是 WinForm 的全部代码:
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using mysql.Data.MySqlClient;
using System.Data.Entity;
using System.Data.Linq;
namespace C969_Software_2
public struct Customer
public string customerName;
public int numberOfApps;
public partial class CustomerReports : Form
public CustomerReports()
InitializeComponent();
customerReportView.DataSource = getReport();
public static DataTable getReport()
string SqlString = "SELECT * FROM customer";
MySqlConnection c = new MySqlConnection(SqlUpdater.conString);
MySqlDataAdapter sda = new MySqlDataAdapter(SqlString, c);
DataTable dt = new DataTable();
c.Open();
sda.Fill(dt);
dt.AsEnumerable()
.Where(i => i.Field<int>("customerId") == 1)
.Select(i => new name = i.Field<string>("customerName"));
return dt;
任何指针将不胜感激!
【问题讨论】:
没有告诉 Lamba 函数做任何事情。这就像一个固定查询,直到需要才执行。您可以通过附加.ToArray()
或.ToList()
使其运行。
AlwaysLearning:感谢您的提示!现在我看到了一些人们能够使用 .CopyToDataTable() 的实例,但在这种情况下似乎不起作用。
.CopyToDataTable()
在这里不起作用,因为它需要 IEnumerable<DataRow>
作为源,而您选择的是 IEnumerable<SomeAnonymousObject>
。即:您的 .Select()
语句正在返回一个新对象。
@PatrickDavis,另外,请在用户名前添加@
符号,以便他们得到通知。
【参考方案1】:
假设您的 Linq 查询的目的是获取 customerId 1 的名称,请尝试以下操作...
//This creates the query as IEnumerable<someAnonymousRuntimeObject> but doesn't execute it.
var query = dt.AsEnumerable()
.Where(i => i.Field<int>("customerId") == 1)
.Select(i => new name = i.Field<string>("customerName") );
//This actually executes the query and stores the result in name
var name = query.FirstOrDefault().name;
=== 编辑 ===
对于您期望从 getReport() 返回的内容有点模糊。
如果正如您的 Linq Select 语句所建议的那样,您只想要 customerName
代替 customerId == 1
,您可以这样做:
var name = dt.AsEnumerable()
.Where(i => i.Field<int>("customerId") == 1)
.Select(i => i.Field<string>("customerName"))
.FirstOrDefault();
return name;
如果你想要一个 DataTable
只包含 customerId == 1
所在的行,你可以这样做:
var dt2 = dt.AsEnumerable()
.Where(i => i.Field<int>("customerId") == 1)
.CopyToDataTable();
return dt2;
这会返回一行,其中包含 customerId、customerName 以及您的 SELECT *
语句返回的任何其他列。
不过,上述方法都不是特别有效。随着您的数据库增长并且客户表包含数千或数百万行,您将向您的 C# 代码返回数千或数百万行,以过滤为仅一行。最好让 SQL 为您进行过滤并仅将所需的单行返回给您的 C# 代码。
您可以使用参数化查询来执行此操作,例如:
public static DataTable getReportById(int customerId)
using (var conn = new MySqlConnection(SqlUpdater.conString))
using (var cmd = conn.CreateCommand())
cmd.CommandText = "SELECT customerName as 'name' FROM customer where customerId = @Id";
cmd.Parameters.AddWithValue("@Id", customerId);
MySqlDataAdapter sda = new MySqlDataAdapter(cmd);
DataTable dt = new DataTable();
sda.Fill(dt);
return dt;
【讨论】:
感谢您的帮助!这似乎不起作用。我只是不断得到同样的东西。我认为这可能是因为 return.dt 但在注释掉之后,getReport 方法没有任何返回... 基本上我试图从数据库中获取一些列,将它们放入数据表中,然后使用 Linq 查询过滤数据表,并将结果显示在 datagridview 中 谢谢!这是一个很大的帮助!我意识到它的效率相当低,但它是一个小型测试数据库,并且使用 Linq/Lambda 是要求的一部分。通常我会使用参数。以上是关于使用Lambda表达式查询SQL语句填充的DataTable的主要内容,如果未能解决你的问题,请参考以下文章