在我的ASP.NET项目中,我有一个名为BrowserStats的数据表,其中包含不同用户的不同浏览器列表。
我想按用户ID对用户进行分组,并使用linq显示特定浏览器(Chrome,Firefox,IE)的访问次数。
我的数据表(BrowserStats)如下:
UserId | Browser ---------------------------- 1 | Chrome-32.0 1 | Chrome-30.0 1 | Chrome-33.0 1 | Firefox-20.0 1 | Firefox-26.0 1 | Safari 1 | IE-9 1 | IE-10 2 | Chrome-31.0 2 | Chrome-32.0 2 | IE-10 2 | Firefox-22.0 2 | Firefox-26.0
我的输出表应该是:
UserId | Chrome | Firefox | IE | Others ----------------------------------------------- 1 | 3 | 2 | 2 | 1 2 | 2 | 2 | 1 | 0
答案 0 :(得分:3)
您可以在LINQ中使用嵌套组: -
var query = from browser in browesers
group browser by browser.UserID into UserGroup
from countGroup in
(from brow in UserGroup
group brow by new
{
Chrome = brow.Browser.Contains("Chrome"),
Firefox = brow.Browser.Contains("Firefox"),
IE = brow.Browser.Contains("IE")
} into test
select new
{
ChromeCount = test.Key.Chrome ? test.Count() : 0,
FirefoxCount = test.Key.Firefox ? test.Count() : 0,
IECount = test.Key.IE ? test.Count() : 0,
OthersCount = (!test.Key.Chrome && !test.Key.Firefox && !test.Key.IE) ? test.Count() : 0
}
)
group countGroup by UserGroup.Key;
我使用了以下类型: -
public class BrowserInfo
{
public int UserID { get; set; }
public string Browser { get; set; }
}
这是工作Fiddle。
答案 1 :(得分:2)
首先,我会考虑LINQ慢。 LINQ几乎是一种嵌套数组迭代逻辑的简洁方法。仅在CPU必须操作静态数据时使用。或数据是CPU生成的,没有后备存储。
无论如何,我是怎么想的。现在回答:
我已经在SQLServer 2012 Express中构建了一个用于恶魔条纹目的的数据库(< -Xanth reference)。我使用了你的浏览器并创造了虚构的用户。数据透视代码应该是您从c#调用的存储过程。如果您正在使用VS我可以编辑纯VS(2012)解决方案,因为我更喜欢使用数据集并向TableAdapter添加查询以使用存储过程。但这应该让你在那里2 / 3rds
用户表::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::::浏览器表::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::
使用表样本(总共324行):::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::
图:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::::::::
PIVOT(我将其作为存储过程添加):::::::::::::::::::::::::::::::::::::::::::::::::: :::::::
VS 2012 / WPF实施::::::::::::::::::::::
添加存储过程后,将VS连接到数据库,并将数据集添加到项目中。将存储过程拖放到数据集中。您也可以使用没有类型化数据集生成器的存储过程。 See Here
WPF XAML ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::::::
<Window x:Class="WPFPIVOT.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid Name="datagrid" ItemsSource="{Binding}"/>
</Grid>
</Window>
的.cs ::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::::::::
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace WPFPIVOT
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
Pivot pivoted;
PivotTableAdapters.GetUsageTableAdapter adapter;
public MainWindow()
{
InitializeComponent();
//this code is the same for WPF and FORMs
pivoted = new Pivot();
adapter = new PivotTableAdapters.GetUsageTableAdapter();
adapter.Fill(pivoted.GetUsage);
///////////////////////////////////////////////////////////////
datagrid.DataContext = pivoted;
}
}
}
WPF WINDOW ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::
(UserID列默认为最右边的列,select语句可以是select p1.UserID,p1[1],... p.[n]
)
答案 2 :(得分:2)
如果你想使用LINQ。它动态地将列和行添加到数据表。输出是数据格式
DataTable dt = new DataTable();
dt.Columns.AddRange(new DataColumn[] { new DataColumn("Browser", Type.GetType("System.String")), new DataColumn("userid", Type.GetType("System.String")) });
dt.Rows.Add(new object[] {"Chrome-32.0","1" });
dt.Rows.Add(new object[] { "Chrome-32.0", "1" });
dt.Rows.Add(new object[] { "Firefox-20.0", "1" });
dt.Rows.Add(new object[] { "Firefox-26.0", "1" });
dt.Rows.Add(new object[] { "Safari", "1" });
dt.Rows.Add(new object[] { "IE-9", "1" });
dt.Rows.Add(new object[] { "IE-10", "1" });
dt.Rows.Add(new object[] { "Chrome-31.0", "2" });
dt.Rows.Add(new object[] { "Chrome-32.0", "1" });
dt.Rows.Add(new object[] { "IE-10", "1" });
dt.Rows.Add(new object[] { "Firefox-22.0", "2" });
DataTable dtOutPut = new DataTable();
dtOutPut.Columns.Add(new DataColumn("UserID", Type.GetType("System.String")));
var tableColumnName = dt.AsEnumerable().Select(s => s.Field<string>("Browser").Trim().ToLower().Split('-')[0].Trim()).Distinct();
foreach (var item in tableColumnName)
{
dtOutPut.Columns.Add(new DataColumn(item, Type.GetType("System.String")));
}
var usrid = dt.AsEnumerable().Select(s => s.Field<string>("userid").Trim()).Distinct();
Parallel.ForEach(usrid, (s) => {
DataRow rec = dtOutPut.NewRow();
rec["UserID"] = s;
foreach (var item in tableColumnName)
{
rec[item] = dt.AsEnumerable().Where(s1 => s1.Field<string>("Browser").Trim().ToLower().Contains(item) && s1.Field<string>("userid") == s).Count();
}
dtOutPut.Rows.Add(rec);
});
输出: