简体   繁体   English

可以使用linq获取值字典吗?

[英]Is possible to get dictionary of values with linq?

I have solution in my mind, but I am convinced that there must be better solution for the problem. 我心中有解决方案,但我坚信必须为该问题找到更好的解决方案。

Lets think I have two tables - User (n..n) Group. 假设我有两个表-用户(n..n)组。 In my app I wish to get list of Users, each with all his Groups. 在我的应用中,我希望获得用户列表,每个用户都有其所有组。 In SQL I can achieve similar result with: 在SQL中,我可以通过以下方式获得类似的结果:

SELECT TOP (1000) u.Name, g.Name
FROM [User] u
join [GroupUser] gu on u.Id = gu.UserId
join [Group] g on gu.GroupId = g.Id

In the code I am able to write something like this (please, don't judge the correctness, it's just for illustration): 在代码中,我可以编写如下代码(请不要判断正确性,仅用于说明):

var result = new Dictionary<Model.User, List<Model.Group>>();
List<string> names = request.Names;
var query = this.dbContext.Set<Model.User>().AsQueryable();

query = from user in query
where names.Contains(user.Name, StringComparer.OrdinalIgnoreCase)
select user;

foreach(var user in await query.ToListAsync())
{
    var groupQuery = 
        from g in this.dbContext.Set<Model.Group>()
        join gu in this.dbContext.Set<Model.GroupUser>() on g.Id equals gu.GroupId
        join u in this.dbContext.Set<Model.User>() on gu.UserId equals u.Id
        where u.Name.Equals(user.Name, StringComparison.OrdinalIgnoreCase)
        select g;

    result.Add(user, await groupQuery.ToListAsync())
}

My question is -- is possible to achieve something like this with single linq query? 我的问题是-是否可以通过单个linq查询实现类似的目标? Or do I really need to enumerate all the Users and fire new query for each of them? 还是我真的需要枚举所有用户并为每个用户触发新查询? This code looks very resource demanding. 此代码看起来非常耗资源。 It is quite simple, only one cycle, but it contains Users.Count+1 query evaluations. 这很简单,只有一个周期,但是它包含Users.Count+1查询评估。

Thanks in advance for hints. 在此先感谢您的提示。

If you have an entity like the following: 如果您具有以下实体:

public class User
{
    // other properties

    public virtual List<Group> Groups { get; set; }
}

You can query both with an Include : 您可以使用Include进行查询:

var users = dbContext.Users.Include(u => u.Groups)
                .Where(u => names.Contains(u.Name, StringComparer.OrdinalIgnoreCase));

Assuming you are using LINQ to SQL, you can combine the queries: 假设您正在使用LINQ to SQL,则可以组合查询:

var requestedUsers = from user in query
                     where names.Contains(user.Name, StringComparer.OrdinalIgnoreCase)
                     select user;

var result = (from u in requestedUsers
              join gu in this.dbContext.Set<Model.User>() on u.UserId equals gu.Id
              join g in this.dbContext.Set<Model.Group>() on gu.UserId equals g.Id into gj
              select new { u, gj })
              .ToDictionary(ugj => ugj.u, ugj => ugj.gj.ToList());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM