从 Linq 查询中删除联接
我有两个这样的实体:
[Table("tblAccount")]
public class Account
{
[Key]
[Column("Creditor Registry ID", Order = 0)]
public int CreditRegistryId { get; set; }
[Key]
[Required]
[Column("Account No", Order = 1)]
public int AccountNo { get; set; }
[Column("Minimum Installment")]
public decimal MinimumInstallment { get; set; }
[Column("Account Status Date")]
public DateTime AccountStatusDate { get; set; }
[Required]
[Column("Account Type")]
public string AccountType { get; set; }
public virtual ICollection<AccountOwner> AccountOwners { get; set; }
}
我
[Table("tblAccountOwner")]
public class AccountOwner
{
[Key]
[ForeignKey("Account")]
[Column("Creditor Registry ID", Order = 0)]
public int CreditorRegistryId { get; set; }
[Key]
[ForeignKey("Account")]
[Column("Account No", Order = 1)]
public int AccountNo { get; set; }
[Key]
[Column("Account Owner Registry ID", Order = 2)]
public long AccountOwnerRegistryId { get; set; }
public virtual Account Account { get; set; }
}
想将以下查询转换为无需连接即可工作,因为帐户实体具有 accountOwners 且 accounOwner 具有帐户导航属性(主键/外键关系)
var ownerRegId = 731752693037116688L;
var excludeTypes = new[] { 'CA00', 'CA01', 'CA03', 'CA04', 'CA02', 'PA00', 'PA01', 'PA02', 'PA03', 'PA04' };
var maxStateChangeMonth = 4;
var excludeStatusId = 999;
var SumOfMonthlyPayments =
context.Accounts
.Join(context.AccountOwners,
a => new { CreditorRegistryId = a.CreditRegistryId, a.AccountNo },
ao => new { ao.CreditorRegistryId, ao.AccountNo },
(a, ao) => new { Account = a, AccountOwner = ao })
.Where(x => x.AccountOwner.AccountOwnerRegistryID == ownerRegId
&& !excludeTypes.Contains(x.Account.AccountType)
&& (x.Account.StateChangeDate == null || x.Account.StateChangeDate.Month - DateTime.Now.Month <= maxStateChangeMonth)
&& x.Account.AccountStatusID != excludeStatusId)
.Sum(x => Math.Abs(x.Account.MinimumInstallment));
正如 Sergi 建议的那样,我发现了这一点:
var sum = (from account in context.Accounts
from owner in account.AccountOwners
where (owner.AccountOwnerRegistryId == ownerRegistryId
&& !excludeTypes.Contains(account.AccountType)
&& (account.StateChangeDate == null ||
(account.StateChangeDate.Month - DateTime.Now.Month)
<= maxStateChangeMonth)
&& account.AccountStatusId != excludeStatusId
&& (includeMortgage.Contains(account.AccountType) ||
account.AccountType.Contains("Mortgage")))
select account.MinimumInstallment)
.Sum(minimumInstallment => Math.Abs(minimumInstallment));
我添加了另一个 & ;&子句
&& (includeMortgage.Contains(account.AccountType) ||
account.AccountType.Contains("Mortgage")
,但现在我得到:
转换为值类型“Decimal”失败,因为物化值为空。结果类型的泛型参数或查询必须使用可为 null 的类型。
谢谢
I have two entities like this:
[Table("tblAccount")]
public class Account
{
[Key]
[Column("Creditor Registry ID", Order = 0)]
public int CreditRegistryId { get; set; }
[Key]
[Required]
[Column("Account No", Order = 1)]
public int AccountNo { get; set; }
[Column("Minimum Installment")]
public decimal MinimumInstallment { get; set; }
[Column("Account Status Date")]
public DateTime AccountStatusDate { get; set; }
[Required]
[Column("Account Type")]
public string AccountType { get; set; }
public virtual ICollection<AccountOwner> AccountOwners { get; set; }
}
and
[Table("tblAccountOwner")]
public class AccountOwner
{
[Key]
[ForeignKey("Account")]
[Column("Creditor Registry ID", Order = 0)]
public int CreditorRegistryId { get; set; }
[Key]
[ForeignKey("Account")]
[Column("Account No", Order = 1)]
public int AccountNo { get; set; }
[Key]
[Column("Account Owner Registry ID", Order = 2)]
public long AccountOwnerRegistryId { get; set; }
public virtual Account Account { get; set; }
}
I want to convert following query to work without join as account entity has accountOwners and accounOwner has account navigation property ( primary key/foreign key relation)
var ownerRegId = 731752693037116688L;
var excludeTypes = new[] { 'CA00', 'CA01', 'CA03', 'CA04', 'CA02', 'PA00', 'PA01', 'PA02', 'PA03', 'PA04' };
var maxStateChangeMonth = 4;
var excludeStatusId = 999;
var SumOfMonthlyPayments =
context.Accounts
.Join(context.AccountOwners,
a => new { CreditorRegistryId = a.CreditRegistryId, a.AccountNo },
ao => new { ao.CreditorRegistryId, ao.AccountNo },
(a, ao) => new { Account = a, AccountOwner = ao })
.Where(x => x.AccountOwner.AccountOwnerRegistryID == ownerRegId
&& !excludeTypes.Contains(x.Account.AccountType)
&& (x.Account.StateChangeDate == null || x.Account.StateChangeDate.Month - DateTime.Now.Month <= maxStateChangeMonth)
&& x.Account.AccountStatusID != excludeStatusId)
.Sum(x => Math.Abs(x.Account.MinimumInstallment));
As Sergi suggested I found this:
var sum = (from account in context.Accounts
from owner in account.AccountOwners
where (owner.AccountOwnerRegistryId == ownerRegistryId
&& !excludeTypes.Contains(account.AccountType)
&& (account.StateChangeDate == null ||
(account.StateChangeDate.Month - DateTime.Now.Month)
<= maxStateChangeMonth)
&& account.AccountStatusId != excludeStatusId
&& (includeMortgage.Contains(account.AccountType) ||
account.AccountType.Contains("Mortgage")))
select account.MinimumInstallment)
.Sum(minimumInstallment => Math.Abs(minimumInstallment));
I added a an other && clauses
&& (includeMortgage.Contains(account.AccountType) ||
account.AccountType.Contains("Mortgage")
but now I get :
The cast to value type 'Decimal' failed because the materialized value is null. Either the result type's generic parameter or the query must use a nullable type.
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
正如您所提到的,您可以使用导航属性而不是联接,因此您可以尝试类似的操作:
两个“连接”
from
子句相当于SelectMany
Linq 中的方法。As you mention, you can use the navigation properties instead of a join, so you could try something like:
The two "concatenated"
from
clauses are equivalent to theSelectMany
method in Linq.