C# 从数据库中选择多个列
我想从数据库中选择三列(用户名、浏览器和浏览器版本),但当我使用第一个变量时,我会为每个用户获得多个结果。我只希望每个用户使用一次他使用的浏览器。使用第二个变量,我只获取一次用户,但不使用浏览器C# 从数据库中选择多个列,c#,sql-server,entity-framework,C#,Sql Server,Entity Framework,我想从数据库中选择三列(用户名、浏览器和浏览器版本),但当我使用第一个变量时,我会为每个用户获得多个结果。我只希望每个用户使用一次他使用的浏览器。使用第二个变量,我只获取一次用户,但不使用浏览器 var browserUser = db.Tracking.Include(t => t.Users).ToList(); var browserUserFiltered = browserUser.GroupBy(x => x.userIdFk).Select(g => g.Firs
var browserUser = db.Tracking.Include(t => t.Users).ToList();
var browserUserFiltered = browserUser.GroupBy(x => x.userIdFk).Select(g => g.First());
实际输出的屏幕截图
数据库模型
尝试按FirstOrDefault选择浏览器和browserVersion:
var browserUserFiltered = browserUser.GroupBy(x => x.userIdFk).Select(g => new {
username= g.FirstOrDefault().username,
browser= g.FirstOrDefault().browser,
browserVersion= g.FirstOrDefault().browserVersion,
});
因此,您有
用户序列
和跟踪序列
。每个用户
都有零个或多个跟踪
,每个跟踪
都只属于一个用户
,使用外键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();
请执行GroupBy:
var browserUserFiltered = browserUser.GroupBy(x => x.userIdFk)
.Select(g => g.First());
结果:2个I组的序列
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之后继续:
var browserUserFiltered = browserUser.GroupBy(x => x.userIdFk)
.Select(g => g.First());
结果:两个项目的顺序,每组一个项目:
Tracking: Id = 10, UserIdFk = 1; User: Id = 1; Name = Jan
Tracking: Id = 12, UserIdFk = 2; User: Id = 2, Name = Piert
问题:为什么您认为结果中只有一项?
在一对多模式中,您可以选择两种方式:
- 获取用户的跟踪信息,这意味着在内部完成组加入。每个用户都会准确地传输到您的流程中一次。没有跟踪数据的用户也在结果中
- 获取跟踪,每个跟踪都有其用户。内部连接完成。如果一个用户有多个跟踪,同一用户数据将被发送多次。没有任何跟踪数据的用户根本不被提及
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(),
});
从npm安装morelinq,然后使用
users.DistinctBy(u=>userId.ToList()
使用SelectMany var browserUserFiltered=browserUser.GroupBy(x=>x.userIdFk)。SelectMany(g=>g.First());请共享跟踪、用户表和所需输出的列。我添加了数据库模型。我想要的输出类似于user1,Chrome,Version xxx-->这在我的数据库中,我想在我的asp.net页面的表格中显示它。@SmightyM8 asp.net是一个web堆栈,不是ORM或数据访问技术。代码执行您告诉它的操作—加载所有跟踪行和所有相关用户。如果您想让用户使用浏览器,您应该从
db.users
和任何相关的跟踪行开始。谢谢,现在我得到了预期的结果。我尝试了这个方法,但得到了一个类型错误。传递到字典的模型元素的类型为“System.Linq.Enumerable+WhereSelectEnumerableInterator2[System.Linq.iGroup
2[System.Int32,WebApp.Models.Tracking],f_uAnonymousType13[WebApp.Models.Users,System.String,System.String]”。但是,此词典需要类型为“System.Collections.Generic.IEnumerable
1[WebApp.Models.Tracking]”的模型元素。谢谢,我已经用类似于您的解决方案解决了它。