如何在Linq和Entity Framework Core中过滤子查询。

huangapple go评论52阅读模式
英文:

How to filter subqueries in Linq and Entity Framework Core

问题

我应该如何筛选子查询?当选择 Payment 实体时,我想选择 Active == true 的项。

表达式:

public async Task<Invoice> InvoiceAsync(Expression<Func<Invoice, bool>> predicate) => await ExecSingleAsync(this.GetDbSet<Invoice>()
    .Include(inv => inv.Actions)
    .Include(inv => inv.Account)
    .Include(inv => inv.Customer)
    .Include(inv => inv.Payments.Where(pm => pm.Active == true)) // 在这里筛选 Payments 实体
    .Include(inv => inv.Lines.Where(ln => ln.Active == true))
    .Where(inv => inv.Active == true)
    .Where(predicate));

Invoice.cs:

public class Invoice : DbAssets, IInvoice
{
    // ... 其他属性和方法

    public IEnumerable<InvoicePayment> Payments { get; set; } = new HashSet<InvoicePayment>();

    // ... 其他属性和方法
}

Payment.cs:

public sealed class InvoicePayment : DbAssets, IInvoicePayment
{
    // ... 其他属性和方法

    public bool Active { get; set; } // 添加 Active 字段

    // ... 其他属性和方法
}

这里我添加了 PaymentsInvoicePayment 类中的 Active 字段筛选。

英文:

How can I filter the subqueries? When selecting Payment entities, I want to select where Active == true.

Expression:

public async Task&lt;Invoice&gt; InvoiceAsync(Expression&lt;Func&lt;Invoice, bool&gt;&gt; predicate) =&gt; await ExecSingleAsync(this.GetDbSet&lt;Invoice&gt;()
	.Include(inv =&gt; inv.Actions)
	.Include(inv =&gt; inv.Account)
	.Include(inv =&gt; inv.Customer)
	.Include(inv =&gt; inv.Payments)
		.Where(pm =&gt; pm.Active)
	.Include(inv =&gt; inv.Lines)
		.Where(ln =&gt; ln.Active)
	.Where(inv =&gt; inv.Active)
	.Where(predicate));

Invoice.cs:

public class Invoice : DbAssets, IInvoice
{
	public int BillingClientId { get; set; }
	public int? CustomerId { get; set; }
	public int AccountId { get; set; }
	public virtual Customer Customer { get; set; }
	public virtual Account Account { get; set; }
	public IEnumerable&lt;InvoiceLine&gt; Lines { get; set; } = new HashSet&lt;InvoiceLine&gt;();
	public DateTime BillingDate { get; set; }
	public DateTime DueDate { get; set; }
	public IEnumerable&lt;InvoiceAction&gt; Actions { get; set; } = new HashSet&lt;InvoiceAction&gt;();
	public string? Message { get; set; }
	public int Nr { get; set; }
	public IEnumerable&lt;InvoicePayment&gt; Payments { get; set; } = new HashSet&lt;InvoicePayment&gt;();

	[NotMapped]
	public decimal Total =&gt; this.Lines.Sum(ln =&gt; ln.Sum);

	[NotMapped]
	public decimal TotalPaid =&gt; this.Payments.Sum(pm =&gt; pm.Amount);

	[NotMapped]
	public InvoiceStatus Status =&gt; this.TotalPaid &gt;= this.Total ? InvoiceStatus.Closed : InvoiceStatus.Open;

	[NotMapped]
	public decimal Mva =&gt; this.Lines.Sum(ln =&gt; ln.Mva);
}

Payment.cs:

public sealed class InvoicePayment : DbAssets, IInvoicePayment
{
	public int InvoiceId { get; set; }
	public DateTime PaymentDate { get; set; }
	public decimal Amount { get; set; }
}

Both classes have an Active field.

答案1

得分: 0

public async Task<Invoice> InvoiceAsync(Expression<Func<Invoice, bool>> predicate) => await ExecSingleAsync(this.GetDbSet<Invoice>()
.Include(inv => inv.Actions)
.Include(inv => inv.Account)
.Include(inv => inv.Customer)
.Include(inv => inv.Payments.Where(p => p.Active))
.Include(inv => inv.Lines)
.Where(inv => inv.Active)
.Where(predicate));

英文:
public async Task&lt;Invoice&gt; InvoiceAsync(Expression&lt;Func&lt;Invoice, bool&gt;&gt; predicate) =&gt; await ExecSingleAsync(this.GetDbSet&lt;Invoice&gt;()
	.Include(inv =&gt; inv.Actions)
	.Include(inv =&gt; inv.Account)
	.Include(inv =&gt; inv.Customer)
	.Include(inv =&gt; inv.Payments.Where(p =&gt; p.Active))
	.Include(inv =&gt; inv.Lines)
	.Where(inv =&gt; inv.Active)
	.Where(predicate));

huangapple
  • 本文由 发表于 2023年4月19日 23:28:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/76056304.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定