c# EntityFramework 查询中筛选活动行的最佳方法

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

c# EntityFramework best way to filter Active rows in queries

问题

The best practice for filtering the deleted date in your code is to use the IsActive property you added to the Invitation class, as you've already done. However, to avoid runtime issues, it's recommended to use .AsAsyncEnumerable() when working with Entity Framework Core in asynchronous scenarios.

Invitation invitation = await db.Invitations
    .AsAsyncEnumerable()
    .Where(invite => invite.IsActive && 
        invite.InvitedUserId == data.MemberId && 
        groupMembers.Contains(invite.InvitedByUserId))
    .FirstOrDefaultAsync();

Using AsAsyncEnumerable() should not significantly impact query loading time, and it ensures that your query is executed asynchronously, which is typically desirable for database operations.

So, to summarize, your approach with AsAsyncEnumerable() is a good practice for filtering inactive records with minimal impact on query performance.

英文:

Trying to understand what is the best way to handle inactive records in the code
i have an Entity with DeletedDate property,

    public class Invitation
    {
        public int Id { get; set; }
        public string InvitedByUserId { get; set; }
  
        ...
        public DateTime? DeletedDate { get; set; }
        
    }

i want to filter the ones that their deleted date is not null,

Invitation invitation = await db.Invitations
  .Where(invite => !invite.DeletedDate.HasValue 
&& invite.InvitedUserId == data.MemberId && 
groupMembers.Contains(invite.InvitedByUserId))
                    .FirstOrDefaultAsync();

i tried to add to the class the function and call it from the code

    public class Invitation
    {
        ...
        public DateTime? DeletedDate { get; set; }
        public bool IsActive => !DeletedDate.HasValue;
    }

    Invitation invitation = await db.Invitations
                    .Where(invite => invite.IsActive && 
invite.InvitedUserId == data.MemberId && 
groupMembers.Contains(invite.InvitedByUserId))
                    .FirstOrDefaultAsync();

but if failes on runtime unless i use it with :

Invitation invitation = await db.Invitations
 .AsAsyncEnumerable()
 .Where(invite => invite.IsActive && 
invite.InvitedUserId == data.MemberId && 
groupMembers.Contains(invite.InvitedByUserId))
                    .FirstOrDefaultAsync();

what is the best practice to filter the deleted date easily, is AsAsyncEnumerable recommended ? or does it make the query loading time longer ?

答案1

得分: 1

问题在于 EF 不知道如何将 invite.IsActive 翻译成 SQL。通过添加 AsAsyncEnumerable(),您正在在客户端内存中执行评估。对于 DeletedDate,使用简单的空值检查。

Invitation invitation = await db.Invitations
    .Where(invite => invite.DeletedDate == null && invite.InvitedUserId == data.MemberId && groupMembers.Contains(invite.InvitedByUserId))
    .FirstOrDefaultAsync();

您还可以找到 全局查询过滤器 有用。

英文:

The problem is that EF doesn't know how to translate invite.IsActive to SQL. By adding AsAsyncEnumerable() you are doing the evaluation in memory on the client side. Use a simple null check for DeletedDate.

Invitation invitation = await db.Invitations
    .Where(invite => invite.DeletedDate == null && invite.InvitedUserId == data.MemberId && groupMembers.Contains(invite.InvitedByUserId))
    .FirstOrDefaultAsync();

You might also find Global Query Filters useful.

答案2

得分: 0

I ended up using Global Query Filters:
我最终使用了全局查询过滤器:

I added to the Framework Entities class - > OnModelCreating the filtering of deleted records:
我将删除记录的过滤添加到了框架实体类中 - > OnModelCreating:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Invitation>()
.HasQueryFilter(invitation => invitation.DeletedDate == null);
}

This way I can use the table and get already filtered values - only active records:
这样我可以使用表格并获取已经过滤的值 - 只有活动记录:

Invitation invitation = await db.Invitations
.Where(invite => invite.InvitedUserId == data.MemberId && groupMembers.Contains(invite.InvitedByUserId))
.FirstOrDefaultAsync();

英文:

I ended up using Global Query Filters :
i added to the Framework Entities class - > OnModelCreating the filtering of deleted records

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity&lt;Invitation&gt;()
            .HasQueryFilter(invitation =&gt; invitation.DeletedDate == null);
    }

this way I can use the table and get already filtered values - only active records:

Invitation invitation = await db.Invitations
    .Where(invite =&gt; invite.InvitedUserId == data.MemberId &amp;&amp; groupMembers.Contains(invite.InvitedByUserId))
    .FirstOrDefaultAsync();

huangapple
  • 本文由 发表于 2023年6月15日 00:33:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/76475754.html
匿名

发表评论

匿名网友

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

确定