在where子句中使用linq

时间:2017-10-11 04:00:49

标签: asp.net entity-framework linq

我有2个表_customerRepository.GetAllQueryable()_customerSettlementRepository.GetAllQueryable()

在表_customerSettlementRepository.GetAllQueryable()中,我有列ApplyD (date),在将这两个一起加入后,我想在where子句中找到max ApplyD。这是我的代码:

var settlements = from c in _customerRepository.GetAllQueryable()
    join cs in _customerSettlementRepository.GetAllQueryable() on new {c.CustomerMainC, c.CustomerSubC}
    equals new {cs.CustomerMainC, cs.CustomerSubC} into c1
    where cs.ApplyD == (c1.Select(b=>b.ApplyD).Max())
    select new CustomerSettlementViewModel()
    {
            TaxRate = cs.TaxRate
    };

2 个答案:

答案 0 :(得分:2)

值得注意的是,在这些问题中,人们常常提出一个SQL(类似)语句而没有规定他们想要达到的目标。因此,无法确定所提供的陈述是否符合要求。

无论如何,您似乎在Customers中有CustomerRepositoryCustomerSettlements}和CustomerSettlementRepository

CustomersCustomerSettlements都有CustomerMainC和CustomerSubC。您希望在这两个属性上加入CustomersCustomerSettlements

CustomerSettlement还有ApplyDTaxRate

您只想保持ApplyD的最大值为ApplyD

的联接结果

最后,从每个剩余的联接结果中,您希望创建一个CustomerSettlementViewModel对象,其中的联接结果中的TaxRate值取自CustomerSettlement

现在我写了这个,它让我感到困惑,为什么你需要首先加入,因为你只使用来自CustomerSettlements的值,而不是来自客户。

此外,如果两个客户加入了相同的CustomerSettlements。这将导致两个相等的CustomerSettlementViewModel对象。

但是,让我们假设这真的是你想要的。

在婴儿步骤中:

IQueryable<Customer> customers = ...
IQueryable<CustomerSettlement> customerSettlements = ...

var joinResults = customers.Join(customerSettlements
   customer => new {customer.CustomerMainC, customer.CustomerSubC},
   settlement => new {settlement.CustomerMainC, settlement.CustomerSubC}
   (customer, settlement) => new
   {
      settlement.ApplyD,
      settlement.TaxRate,
      // add other properties from customers and settlements you want in the end result
   });

单词:全部Customers和全部CustomerSettlements。从每个Customer创建一个具有客户CustomerMainCCustomerSubC值的对象。从每个CustomerSettlement做同样的事情。当这两个对象相等时,创建一个新对象,其值为CustomerSettlement&#39; s ApplyDTaxRate(以及最终结果中需要的其他属性)< / p>

请注意,这仍然是一个IQueryable。尚未执行任何查询。

从这个joinResult开始,你只想保留那些具有ApplyD值的对象等于ApplyD的最大值。

This question on StackOverflow is about selecting the records with the max value。我们的想法是将记录分组为ApplyD具有相同值的组。然后按降序键顺序对组进行排序并获取第一组。

var groupsWithSameApplyD = joinResults.GroupBy(
    joinedItem => joinedItem.ApplyD,
    joinedItem => new CustomerSettlementViewModel()
    {
        TaxRate = orderedItem.TaxRate,
        // add other values from joinedItems as needed
    });

groupsWithSameApplyD中的每个组都有一个等于ApplyD的键。该组包含从joinedItems创建的CustomerSettlementViewModel对象,这些对象都具有该组Key中的相同ApplyD。

现在按降序排序:

var orderedGroups = groupsWithSameApplyD.OrderByDescending(group => group.Key);

第一组包含具有最大ApplyD的所有元素。您期望的结果是组中元素的序列。

如果根本没有组,则返回空序列。请注意,如果请求序列作为结果,则返回空序列而不是null总是更好,因此调用者可以在foreach中使用返回的值而无需检查null返回

var result = orderedGroups.FirstOrDefault() ??
    // if no groups at all, return empty sequence:
    Enumerable.Empty<CustomerSettlementViewModel>();

注意:FirstOrDefault是实际执行查询的第一步。如果需要,您可以将所有内容放在一个大查询中。不确定这是否会提高可读性和可维护性。

答案 1 :(得分:0)

enter image description here

这是我的syntet错误,我需要从第一次开始写这个

var settlements = from c in _customerRepository.GetAllQueryable()
                    join cs in _customerSettlementRepository.GetAllQueryable() on new {c.CustomerMainC, c.CustomerSubC}
                        equals new {cs.CustomerMainC, cs.CustomerSubC} 
                    select new CustomerSettlementViewModel()
                    {
                        TaxRate = cs.TaxRate
                    };
                settlements = settlements.Where(p => p.ApplyD == settlements.Max(b => b.ApplyD));