声明并初始化变量,用于分配匿名类型列表。

3

我尝试连接两个表:

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();

这就是我的困境所在。当我没有连接(join)操作,只检索"Request"类型时,我可以声明一个"Requests"列表。

List<Requests> req;

但是,使用Requests和AutolineAccts的组合,我必须声明和初始化一个“items”列表(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
                });

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

1
使用dynamic关键字来创建匿名类型。 - Eugene Ogongo
为什么不在过滤之前投影到 IEnumerable<IndexViewModel> - Johnathan Barclay
哦,我到目前为止还不知道动态类型。虽然我得到了一个新的错误消息,表明我不能连接来自不同数据库/上下文的两个表,但这似乎可以工作。“InvalidOperationException:无法在单个查询执行中使用多个DbContext实例。确保查询使用单个上下文实例。”但那是另一个问题... - d00d
2个回答

0

避免使用 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
@AndiChin:你认为这会导致内存泄漏吗?它创建了一个立即适合进行垃圾回收的对象。从内存方面来看,这可能效率有点低,但这与泄漏是非常不同的。(为了避免过多内存使用,你可以尝试仅执行一次,尽管可能增加一些复杂性。) - Jon Skeet

0
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};

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

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接