导语
Linq在几年前写的代码程序中用过,后来因为lambda表达式的方式,很多地方直接用lambda就可以实现了,所以几乎没再用过Linq的查询,前两天的做的.net5的项目中因为要两个List中进行分组查询,发现这种方式的还没用过,查了一下用法这里顺便做一下记录。
创建项目
微卡智享
新建了一个windows from App(Net)的项目,也就是.net5的winform,起名为LinqDemo。
代码区域中和.net framework差不多,在框架里面可以看到依赖的是Microsoft.NETCore.App和Microsoft.WindowsDesktop.APP这两个,窗体的布局。
项目的属性中默认生成的是.NET Core 3.1的,我们改为.NET 5.0。说起来更新.net 5后,Winform的窗体设计器也是有了,以前只是.net core 3.1的时候也尝试过创建Winform的程序,结果没有窗体设计器而放弃了。
创建了三个类,一个销售流水Sales类和一个基础信息类Plu,另一个就是汇总的数据类。
Plu
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LinqDemo
{
public class Plu
{
//商品编码
public string incode = "";
//商品名称
public string fname = "";
//商品规格
public string specs = "";
//商品单位
public string unit = "";
//商品单价
public float price = 0f;
}
}
Sales
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LinqDemo
{
public class Sales
{
//商品编码
public string incode = "";
//销售日期
public string sdate = DateTime.Now.ToString("yyyy-MM-dd");
//销售时间
public string stime = DateTime.Now.ToString("HH:mm:ss");
//销售数量
public int qty = 0;
//销售金额
public float total = 0f;
}
}
SumSales
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LinqDemo
{
public class SumSales
{
//商品编码
public string incode;
//商品名称
public string fname;
//销售日期
public string sdate;
//销售数量
public int qty;
//销售金额
public float total;
}
}
在窗体布局中加入了一个textBox用于显示结果,一个Button用于处理两个List分组求和。
using System;
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;
namespace LinqDemo
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//随机生成商品列表
private List<Plu> initPlus()
{
List<Plu> plus = new List<Plu>();
int count = new Random().Next(3, 5);
for (int i = 0; i < count; ++i)
{
Plu item = new Plu();
item.incode = i.ToString().PadLeft(5, '0');
item.fname = "测试商品" + i;
item.specs = "250ml";
item.unit = "支";
item.price = new Random().Next(1, 10);
plus.Add(item);
}
return plus;
}
//根据商品随机生成销售数据
private List<Sales> initSales(List<Plu> plus)
{
List<Sales> sales = new List<Sales>();
foreach (Plu item in plus)
{
int count = new Random().Next(1, 5);
for (int i = 0; i < count; ++i)
{
Sales sale = new Sales();
sale.incode = item.incode;
sale.stime = DateTime.Now.AddMinutes(i).ToString("HH:mm:ss");
sale.qty = new Random().Next(1, 10);
sale.total = item.price * sale.qty;
sales.Add(sale);
}
}
return sales;
}
private void btnSum_Click(object sender, EventArgs e)
{
//生成商品列表
List<Plu> plus = initPlus();
tbMsg.AppendText("商品信息:\r\n");
plus.ForEach(p =>
tbMsg.AppendText("编码:"+p.incode + " 名称:" + p.fname + " 价格:" + p.price + "\r\n"));
//生成流水数据
List<Sales> sales = initSales(plus);
tbMsg.AppendText("销售流水:\r\n");
sales.ForEach(t => tbMsg.AppendText("编码:"+t.incode + " 时间:" + t.sdate + " " + t.stime
+ " 数量:" + t.qty + " 金额:" + t.total+"\r\n"));
//Linq分组查询
var lists = (from a in plus
from b in sales
where a.incode == b.incode
group b by new { a.incode, a.fname, b.sdate }
into tmp
select new SumSales
{
incode = tmp.Key.incode,
fname = tmp.Key.fname,
sdate = tmp.Key.sdate,
qty = tmp.Sum(t => t.qty),
total = tmp.Sum(t => t.total)
}).ToList();
tbMsg.AppendText("分组数据:\r\n");
lists.ForEach(t =>
tbMsg.AppendText("编码:" + t.incode + " 名称:" + t.fname + " 销售数量:" + t.qty + " 销售金额:" + t.total + "\r\n")
);
}
}
}
实现效果
上面图中可以看出来,随机生成的商品流水和商品信息,通过两个List的集合实现了分组求和。
完