我对下面的代码有一个问题。
public IEnumerable<BillingConfiguration> GetBillingConfigurationsForAccount(int accountId, DateTime? effectiveDate)
{
var result = new List<BillingConfiguration>();
var accountIds = new List<int>();
var billingGroupIds = new List<int>();
using (var context = new GbContext())
{
var account = context.Accounts.Where(a => a.AccountId == accountId).SingleOrDefault();
if (account.ParentAccountId == null) // This is a parent account
{
// Get list of sub account ids
accountIds = context.Accounts.Where(a => a.ParentAccountId == accountId).Select(x => x.AccountId).ToList();
accountIds.Add(accountId);
}
else // This is a sub account
{
accountIds.Add(accountId);
}
// Get list of Billing Configurations for all accountIds
IQueryable<BillingConfigurationAccount> accountQuery = context.BillingConfigurationAccounts
.Where(a => accountIds.Contains(a.AccountId)).AsQueryable();
AddBillingConfigurationAccountIncludes(accountQuery);
var accountBillingConfigurations = accountQuery.ToList();
//IQueryable<BillingConfigurationAccount> accountQuery = context.BillingConfigurationAccounts;
//AddBillingConfigurationAccountIncludes(accountQuery);
//accountQuery = accountQuery.Where(a => accountIds.Contains(a.AccountId));
//var accountBillingConfigurations = accountQuery.ToList();
if (accountBillingConfigurations.HasValues())
{
accountBillingConfigurations.ForEach(x => result.Add(x.BillingConfiguration));
}
return result;
}
}
private void AddBillingConfigurationAccountIncludes(IQueryable<BillingConfigurationAccount> query)
{
query = query
.Include(p => p.BillingConfiguration)
.Include(p => p.BillingConfiguration.BillingConfigurationLevel)
.Include(p => p.BillingConfiguration.BillType)
.Include(p => p.BillingConfiguration.PayerOptionType)
.Include(p => p.BillingConfiguration.BillModeOptions)
.Include(p => p.BillingConfiguration.BillModeOptions.Select(m => m.BillMode))
.Include(p => p.BillingConfiguration.BillModeOptions.Select(m => m.FirstPastDueDateOptionsType))
.Include(p => p.BillingConfiguration.BillModeOptions.Select(m => m.LapseNoticeOptionsType))
.Include(p => p.BillingConfiguration.BillModeOptions.Select(m => m.PaymentDueDateOptionsType))
.Include(p => p.BillingConfiguration.BillModeOptions.Select(m => m.PaymentGracePeriodType))
.Include(p => p.BillingConfiguration.BillModeOptions.Select(m => m.SecondPastDueDateOptionsType))
.Include(p => p.BillingConfiguration.BillModeOptions.Select(m => m.BillModeOptionPaymentMethods))
.Include(p => p.BillingConfiguration.BillModeOptions.Select(m => m.BillModeOptionPaymentMethods.Select(n => n.PaymentMethodType)));
}
当我查看accountBillingConfigurations
时,它在列表中有2个项目,然而BillingConfiguration
实体为空,BillingConfigurationId
存在并且正确,但它没有带回BillingConfiguration
实体。
现在,如果我像这样做所有内联,它会像预期的那样工作。where子句和include是相同的。
public IEnumerable<BillingConfiguration> GetBillingConfigurationsForAccount(int accountId, DateTime? effectiveDate)
{
var result = new List<BillingConfiguration>();
var accountIds = new List<int>();
var billingGroupIds = new List<int>();
using (var context = new GbContext())
{
var account = context.Accounts.Where(a => a.AccountId == accountId).SingleOrDefault();
if (account.ParentAccountId == null) // This is a parent account
{
// Get list of sub account ids
accountIds = context.Accounts.Where(a => a.ParentAccountId == accountId).Select(x => x.AccountId).ToList();
accountIds.Add(accountId);
}
else // This is a sub account
{
accountIds.Add(accountId);
}
// Get list of Billing Configurations for all accountIds
var accountBillingConfigurations = context.BillingConfigurationAccounts
.Include(p => p.BillingConfiguration)
.Include(p => p.BillingConfiguration.BillingConfigurationLevel)
.Include(p => p.BillingConfiguration.BillType)
.Include(p => p.BillingConfiguration.PayerOptionType)
.Include(p => p.BillingConfiguration.BillModeOptions)
.Include(p => p.BillingConfiguration.BillModeOptions.Select(m => m.BillMode))
.Include(p => p.BillingConfiguration.BillModeOptions.Select(m => m.FirstPastDueDateOptionsType))
.Include(p => p.BillingConfiguration.BillModeOptions.Select(m => m.LapseNoticeOptionsType))
.Include(p => p.BillingConfiguration.BillModeOptions.Select(m => m.PaymentDueDateOptionsType))
.Include(p => p.BillingConfiguration.BillModeOptions.Select(m => m.PaymentGracePeriodType))
.Include(p => p.BillingConfiguration.BillModeOptions.Select(m => m.SecondPastDueDateOptionsType))
.Include(p => p.BillingConfiguration.BillModeOptions.Select(m => m.BillModeOptionPaymentMethods))
.Include(p => p.BillingConfiguration.BillModeOptions.Select(m => m.BillModeOptionPaymentMethods.Select(n => n.PaymentMethodType)))
.Where(a => accountIds.Contains(a.AccountId));
if (accountBillingConfigurations.HasValues())
{
accountBillingConfigurations.ForEach(x => result.Add(x.BillingConfiguration));
}
return result;
}
}
该代码实际上填写了BillingConfiguration
实体及其所有子实体。我想做的事有可能吗?如果我做错了什么?
谢谢
这是一个微妙的问题。
您可以正确地假设像
这样的方法void SomeMethod(IQueryable<T> query)
可以修改它接收到的引用对象,并且这些修改将在方法作用域之外可见。
然而…该方法不修改对象,而是替换对象。赋值=
将Include
方法的返回值赋给query
变量。现在在方法中,前面的query
变量超出了作用域,因为引用被对新对象的引用覆盖了。但是在方法之外,这个新的引用将永远不会被知道。这里,旧的引用仍然适用。
IQueryable<T> SomeMethod(IQueryable<T> query)
在你的情况下,这将变成:
accountQuery = AddBillingConfigurationAccountIncludes(accountQuery);
如果你不相信我,试试这个小程序在Linqpad:)
void Main()
{
var ints = Enumerable.Range(1,10).ToArray();
AddInt(ints, 11);
ints.Dump();
}
void AddInt(IEnumerable<int> list, int i)
{
list = list.Concat(new[] {i});
list.Dump();
}