我有这个域名:
public class User
{
public long Id { get; set; }
public string Login { get; set; }
public string Password { get; set; }
}
public class Application
{
public long Id { get; set; }
public string Name { get; set; }
}
public class UserApplications
{
[ForeignKey("User")]
public long UserId { get; set; }
public User User { get; set; }
[ForeignKey("Application")]
public long ApplicationId { get; set; }
public Application Application { get; set; }
public DateTime LastConnection { get; set; }
}
我想做一个返回类似的选择:
List of select new
{
User = user,
Applications = applications // List of all user's applications
}
我试试:
from u in Users
join ua in UserApplications on u.Id equals ua.UserId into userApplications
from ua in userApplications.DefaultIfEmpty()
join a in Applications on ua.ApplicationId equals a.Id into applications
select new
{
User = u,
Applications = applications
}
但是这会将用户重复到每个应用程序。
我知道我可以在两个选择语句中执行此操作,但我不希望这样。
我该怎么做?
答案 0 :(得分:2)
我不记得Entity Frameworks是否可以基于实体对象本身groupby
(并在场景后面提取它Id
并替换适合的东西等);但是这段代码适用于这种情况:
var q = from uapp in cntxt.UserApplications
group uapp by uapp.UserId
into g
select new { UserId = g.Key, Applications = g.Select(x => x.Application) };
如果您愿意提取User
:
var q2 = from uapp in cntxt.UserApplications
group uapp by uapp.UserId
into g
let u = Users.First(x => x.Id == g.Key)
select new { User = u, Applications = g.Select(x => x.Application) };
假设您正在针对实体框架上下文编写查询 - 而不仅仅是尝试执行Linq to Objects查询。
答案 1 :(得分:1)
试试这个:
var tmp =
from u in Users
join ua in UserApplications on u.Id equals ua.UserId
join a in Applications on ua.ApplicationId equals a.Id
select new
{
User = u,
App = a
};
var res = tmp
.ToArray() // edited
.GroupBy(_ => _.User)
.Select(_ => new
{
User = _.Key,
Applications = _.Select(_ => _.App).ToArray()
});
答案 2 :(得分:1)
实际上,您只需对用户设置的UserApplications
实体进行分组:
context
.UserApplications
.GroupBy(_ => _.User, _ => _.Application)
.ToList();
因为,实际上,IGrouping<User, Application>
是您所需要的(Key
是用户,而组项是他的应用程序。)
任何其他改进都是品味问题,比如投射到匿名类型:
context
.UserApplications
.GroupBy(_ => _.User, _ => _.Application)
.Select(_ => new
{
User = _.Key,
// since IGrouping<User, Application> is IEnumerable<Application>,
// we colud return a grouping directly
Applications = _
})
.ToList();
(另一个投影选项会抛弃Applications
中的组密钥):
context
.UserApplications
.GroupBy(_ => _.User, _ => _.Application)
.Select(_ => new
{
User = _.Key,
Applications = _.Select(app => app)
})
.ToList();