我想从数据库中选择三列(用户名,浏览器和浏览器版本),但是当我使用第一个变量时,每个用户得到多个结果。我只希望每个用户使用他使用的浏览器一次。使用第二个变量,我只获得一次用户,但没有浏览器。
var browserUser = db.Tracking.Include(t => t.Users).ToList();
var browserUserFiltered = browserUser.GroupBy(x => x.userIdFk).Select(g => g.First());
答案 0 :(得分:1)
尝试通过FirstOrDefault选择浏览器和browserVersion:
var browserUserFiltered = browserUser.GroupBy(x => x.userIdFk).Select(g => new {
username= g.FirstOrDefault().username,
browser= g.FirstOrDefault().browser,
browserVersion= g.FirstOrDefault().browserVersion,
});
答案 1 :(得分:1)
因此,您有Users
和Trackings
的序列。每个User
都具有零个或多个Trackings
,每个Tracking
都使用外键User
恰好属于一个UserIdFk
。简单的一对多关系。
User Tracking
Id | Name Id | UserIdFk | <other properties>
1 | Jan 10 | 1 | A
2 | Piert 11 | 1 | B
12 | 2 | C
var browserUser = db.Tracking.Include(t => t.Users).ToList();
结果:3个跟踪的序列,每个跟踪及其用户
Tracking: Id = 10, UserIdFk = 1; User: Id = 1; Name = Jan
Tracking: Id = 11, UserIdFk = 1; User: Id = 1; Name = Jan
Tracking: Id = 12, UserIdFk = 2; User: Id = 2, Name = Piert
执行分组依据:
var browserUserFiltered = browserUser.GroupBy(x => x.userIdFk)
结果:2个IGrouping的序列
Group Key: 1; Elements:
Tracking: Id = 10, UserIdFk = 1; User: Id = 1; Name = Jan
Tracking: Id = 11, UserIdFk = 1; User: Id = 1; Name = Jan
Group Key: 2; Elements:
Tracking: Id = 12, UserIdFk = 2; User: Id = 2, Name = Piert
在GroupBy之后继续:
.Select(g => g.First());
结果:两个项目的序列,每组一个项目:
Tracking: Id = 10, UserIdFk = 1; User: Id = 1; Name = Jan
Tracking: Id = 12, UserIdFk = 2; User: Id = 2, Name = Piert
问题:为什么您认为结果中只有一项?
一对多,您可以采用两种方式:
由您决定自己想要什么。
数据库查询的较慢部分之一是将所选数据传输到您的流程。因此,限制所选数据量是明智的。
如果用户4具有1000个跟踪,那么每个跟踪将具有一个外键UserId,其值等于4。如果您使用Include选择数据,则相同的外键值将被发送1000次,而您已经知道它等于用户主键的值:4.太浪费了!
查询数据时,请始终使用“选择”并仅选择您实际计划使用的属性。仅在计划更新包含的项目时才使用“包含”。
因此,要通过(某些)跟踪获取某些用户,请执行以下查询:
var result = dbContext.Users
.Where(user => ...) // only if you don't want all Users
.Select(user => new
{
// Select only the User data you actually plan to use
Id = user.Id,
Name = user.Name,
...
Trackings = user.Trackings
.Where(tracking => tracking.Date >= startDate) // only if you don't want all Trackings
.Select(tracking => new
{
// again: select only the properties you plan to use
Id = tracking.Id,
Name = tracking.Name,
...
// not needed, you know the value: UserId = tracking.UserId
})
.ToList(),
});
答案 2 :(得分:0)
从npm安装morelinq,然后使用users.DistinctBy(u=>userId).ToList()