c# - 如何在 Linq 和 EF 中订购嵌套集合

标签 c# linq entity-framework frameworks entity

我想为我的数据创建一个树 ListView 。

树应该是这样的

Accounts
-> Providers
-> Accounts

public sealed class AccountRoot    
{
    public AccountRoot()
    {
        Providers = new Collection<Hoster>();
    }

    public long AccountRootId { get; set; }
    public ICollection<Hoster> Providers { get; set; } 

}

public sealed class Hoster
{
    public Hoster()
    {
        Accounts = new Collection<Account>();
    }

    [Key]
    public long HosterId { get; set; }
    public long AccountRootId { get; set; }
    public string Name { get; set; }

    public ICollection<Account> Accounts { get; set; } 
}

public sealed class Account
{
    [Key]
    public long AccountId { get; set; }
    public long HosterId { get; set; }
    public Hoster Hoster { get; set; }
    public string Name { get; set; }
}

我想订购我的查询。

应该是这样的

帐户
供应商A-Z
帐户A-Z

我到现在为止得到的是..

var query = _entity.AccountRoot.Local
                   .Select(x => new AccountRoot()
                   {
                        AccountRootId = x.AccountRootId,
                        Providers = x.Providers.OrderBy(y => y.Name).ToList()
                   }).ToList();

缺少的是下一个嵌套集合的 orderby

感谢您的帮助! :-)

最佳答案

根据您是否已经有了一个结果集,并且只想在代码中对其进行排序,或者您是否想要构造 IQueryable<>,这可能会有所不同。对于 EF,它将成功编译为 SQL 并在数据库中进行实际排序。

首先,假设您已经在代码中拥有该集合。在这种情况下,您有对象 AccountRoot ,其中包含 Providers 的集合, 每个都有 Accounts 的集合.显然,您不能返回相同的对象,因为您需要重新排序集合属性,所以您只需要构造新的对象即可。我只会对集合进行排序,但如果需要,您可以构建全新的实体:

var query = ...
    .Select(x => new AccountRoot
    {
        // add copy properties here
        // ....
        Providers = x.Providers
                        .Select(y =>
                        {
                            // Here we can construct completely new entity, 
                            // with copying all properties one by one,
                            // or just reorder existing collection as I do here
                            var result = y;
                            result.Accounts = y.Accounts.OrderBy(z => z.Name).ToArray();
                            return result;
                        })
                        .OrderBy(y => y.Name)
                        .ToArray()
    })
    .ToArray();

第二种情况,如果您需要直接从 SQL 获取它,则有点不同,因为您不能使用所有 var result = ...; ... return result lambda 中的东西 - 它不会编译为 SQL。但想法是一样的——你需要从数据集构建投影。它应该是这样的:

var query = ...
    .Select(x => new AccountRoot
    {
        AccountRootId = x.AccountRootId,
        // Other properties to copy
        // ...
        Providers = x.Providers
                        .Select(y => new Hoster
                        {
                            HosterId = y.HosterId,
                            // Other properties to copy
                            // ...
                            Accounts = y.Accounts.OrderBy(z => z.Name).ToArray(),
                        })
                        .OrderBy(y => y.Name)
                        .ToArray()
    })
    .ToArray();

关于c# - 如何在 Linq 和 EF 中订购嵌套集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25445519/

相关文章:

c# - 通过文件元数据 .NET Core 3.1 C# 查找 PNG 图像宽度/高度

asp.net - 带有外部 connectionStrings.config 文件的 WebPublish Code-First 迁移

sql - INSERT statement conflict with the FOREIGN KEY constraint 冲突发生在数据库中

.net - 使用 Entity Framework Code First 迁移添加数据库触发器

c# - 将 JWT 声明作为数组添加?

c# - 有没有办法确保 Orleans Grains 最终进入同一个筒仓

c# - CaSTLe Windsor/DelegatingHandler/IPrincipal 依赖注入(inject) (DI)/ASP.NET Web API 中的控制反转 (IoC)

c# - Linq 查询中的 .OrderBy 并不总是正确排序

c# - ToList 性能较慢 vs foreach 性能较慢

c# - 如何在 lambda 表达式中返回不同的数据类型?