【问题标题】:Declare and initialize variable for assigning list of anonymous types声明并初始化用于分配匿名类型列表的变量
【发布时间】:2020-05-29 17:55:39
【问题描述】:

我尝试加入两个表:

var data = from request in context.Requests
                        join account in context.AutolineAccts
                            on request.PkRequest.ToString() equals account.AccountCode
                        select new 
                        {
                            ID = request.PkRequest.ToString(),
                            Location = request.FkLocation,
                            RequestDate = request.RequestDate.Value,
                            Requestor = request.FkRequestor,
                            DebitorNr = request.FkDebitor.ToString(),
                            NewDebit = request.Debit.ToString(),
                            ApprovalStatus = request.ApprovalStatus.ToString(),
                            RecommendationStatus = request.RecommendationStatus.ToString(),
                            DebitorName = account.CustomerSname,
                            Limit = account.CreditLimit
                        };

现在我想根据用户的状态过滤结果集:

// Accounting user
if (ActiveDirectoryHelper.CheckIfUserIsInADGroup(userLogin, AdGroups.ACCOUNTING) )

    req = data.Where(x => x.RecommendationStatus == null).ToList();

// After sales manager
else if (ActiveDirectoryHelper.CheckIfUserIsInADGroup(userLogin, AdGroups.SAV_LEADERS))
    req = data.OrderByDescending(x => x.ID).ToList();

// Everybody else
else 
    req = data.OrderByDescending(x => x.PkRequest).ToList();

这就是我卡住的地方。当我没有加入并且只检索“请求”类型时,我可以声明一个请求列表

List<Requests> req;

但是对于 Requests 和 AutolineAccts 的组合,我必须声明并初始化一个“项目”(req)列表,以将结果集分配给 if-else 段。但我不知道那个匿名变量应该是什么样子。

稍后我必须将结果集映射到我的 IndexViewModels 列表:

foreach (var item in req)
                viewModel.CLModels.Add(new IndexViewModel
                {
                    ID = item .PkRequest.ToString(),
                    Location = item .FkLocation,
                    RequestDate = item .RequestDate.Value,
                    Requestor = item .FkRequestor,
                    DebitorNr = item .FkDebitor.ToString(),
                    NewDebit = item .Debit.ToString(),
                    ApprovalStatus = item .ApprovalStatus.ToString(),
                    RecommendationStatus = item .RecommendationStatus.ToString(),
                    DebitorName = item.CustomerSname,
                    Limit = item.CreditLimit
                });

有解决这个问题的办法吗?

【问题讨论】:

  • 对匿名类型使用动态
  • 过滤前为什么不投影到IEnumerable&lt;IndexViewModel&gt;?
  • 哦,目前还不知道动态类型。这似乎可行,尽管我收到一条新错误消息,表明我无法连接来自不同数据库/上下文的两个表“InvalidOperationException:无法在单个查询执行中使用多个 DbContext 实例。确保查询使用单个上下文实例。”但这是一个不同的问题......

标签: c# asp.net-core


【解决方案1】:
IEnumerable<dynamic> result = from request in requests
                    join account in accounts
                        on request.id equals account.id
                        select new {id=request.id, name=account.name};

保留访问器,可以进一步查询,是方法的返回类型。

【讨论】:

    【解决方案2】:

    避免dynamic 的一个选择是给编译器一个你的匿名类型的例子:

    var req = new[]
    {
        new
        {
            ID = "",
            Location = "",
            RequestDate = DateTime.Now,
            Requestor = "",
            DebitorNr = "",
            NewDebit = "",
            ApprovalStatus = "",
            RecommendationStatus = "",
            DebitorName = "",
            Limit = 0
        }
    }.ToList();
    

    显然您应该调整值以匹配您期望的类型。

    这有点难看,但我个人更喜欢使用动态类型。

    如果你想避免实际分配数组和列表,你可以以一种相当可怕的方式使用类型推断:

    // Simple method that returns null, but enables type inference
    public static List<T> ProvideNullList(T sample) => null;
    
    // Call it when you want to declare your variable:
    var sample = new
    {
        ID = "",
        Location = "",
        RequestDate = DateTime.Now,
        Requestor = "",
        DebitorNr = "",
        NewDebit = "",
        ApprovalStatus = "",
        RecommendationStatus = "",
        DebitorName = "",
        Limit = 0
    };
    var req = GenericHelpers.ProvideNullList(sample);
    

    这仍然会分配样本,但它至少比数组和列表好位。

    【讨论】:

    • 这不是最好的方法,因为可能会导致内存泄漏
    • @AndiChin:你怎么相信会泄露内存?它创建一个立即符合垃圾收集条件的对象。它在内存方面可能有点低效,但这与泄漏非常不同。 (你可以一次性避免内存流失,可能......但代价是更复杂。)
    猜你喜欢
    • 2015-12-23
    • 1970-01-01
    • 2018-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多