Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .NET核心自访问查询过滤器_C#_.net Core_Entity Framework Core_.net Core 3.1_Ef Core 3.1 - Fatal编程技术网

C# .NET核心自访问查询过滤器

C# .NET核心自访问查询过滤器,c#,.net-core,entity-framework-core,.net-core-3.1,ef-core-3.1,C#,.net Core,Entity Framework Core,.net Core 3.1,Ef Core 3.1,我在找一份工作,为一个年轻人工作。我正在尝试编写一个自动过滤的查询 免责声明:我所做的事情比通过显式用户ID进行过滤要复杂一些,为了简单起见,我只是将其与硬编码值一起使用,因为确切的实现与我的问题无关 protectedoverride-void-onmodellcreating(ModelBuilder-ModelBuilder)=> modelBuilder.Entity() .HasQueryFilter(x=>x.Conversation.ConversationSubscription

我在找一份工作,为一个年轻人工作。我正在尝试编写一个自动过滤的查询

免责声明:我所做的事情比通过显式
用户ID进行过滤要复杂一些,为了简单起见,我只是将其与硬编码值一起使用,因为确切的实现与我的问题无关

protectedoverride-void-onmodellcreating(ModelBuilder-ModelBuilder)=>
modelBuilder.Entity()
.HasQueryFilter(x=>x.Conversation.ConversationSubscriptions
.Select(c=>c.UserId).Contains(315)
);
由于查询筛选器试图访问其筛选的实体,因此它最终会进入一个无休止的循环。由于我们使用的是
ModelBuilder
而不是
DbSet
,因此无法将其标记为
IgnoreQueryFilters

鉴于此,我尝试使用当前上下文来过滤自身:

modelBuilder.Entity().HasQueryFilter(x=>
this.Set cs.ConversationId==x.ConversationId)
.Select(c=>c.UserId)
.包括(315)
);
但是,这会引发一个
invalidoOperationException
,很可能是因为我们试图在完成
OnModelCreating
之前使用上下文

我觉得如果我能以某种方式将
conversationsubscriptions
选择为匿名类型,这样它们就不会被过滤,那么我就有办法绕过这个问题

编辑:我尝试使用匿名类型破解此问题,但没有成功

modelBuilder.Entity().HasQueryFilter(c=>
x=>x.Conversation.Messages.Select(m=>new{
Value=m.Conversation.ConversationSubscriptions.Distinct()
.Select(cs=>cs.UserId).Contains(c.Variable(this.\u UserId))
}).FirstOrDefault().Value
);

约翰尼,也许我在这里遗漏了一些明显的东西,所以如果我偏离了目标,我道歉

但我觉得你在这么做:

  • 从会话订阅,加入会话,然后加入用户id=315的会话订阅
虽然您可以/应该这样做:

  • 从用户id=315的会话订阅中加入会话。
我看不出查询中的往返有什么必要,因为看起来您是从ConversationSubscription查询的。在这样的查询中,简单的include将只返回用户有权访问的对话和会话订阅。这不是你想要的回报吗

var result=context.ConversationSubscriptions.Include(c=>c.Conversation.ToList()

private int\u userId=315;
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
modelBuilder.Entity()
.HasQueryFilter(x=>x.UserId.Contains(_UserId));
}

查询筛选器最初不支持访问导航属性或数据库集。看起来EF Core 3.0删除了这些限制(可能是因为新模式),但有以下限制/缺陷:

  • AsNoTracking()
    AsTracking()
    -不受支持,这是有道理的,因为查询筛选器总是转换为SQL

  • Include
    /
    然后Include
    -允许,但由于相同的原因被忽略

  • IgnoreQueryFilters
    -不支持。这可能被认为是错误,因为它可能被用来解决下一个案例

  • 通过导航属性或数据库集进行交叉引用筛选器(例如,实体
    A
    筛选器使用实体
    B
    和实体
    B
    筛选器使用实体
    A
    ),因为筛选器试图相互使用。这是一个错误

  • 通过导航属性的自引用过滤器-与#4相同的错误,应该类似于#6

  • 通过db集合的自引用筛选器-受支持(!),在筛选器子查询中始终被忽略

  • 尽管如此,幸运的是,您的案例得到了#6的支持,即您的第二次尝试仅删除了不受支持的
    AsNoTracking()
    IgnoreQueryFilters()

    modelBuilder.Entity<ConversationSubscription>().HasQueryFilter(x => 
        this.Set<ConversationSubscription()
            .Where(cs => cs.ConversationId == x.ConversationId)
                  .Select(c => c.UserId)
                  .Contains(315));
    
    modelBuilder.Entity().HasQueryFilter(x=>
    this.Set cs.ConversationId==x.ConversationId)
    .Select(c=>c.UserId)
    .包含(315));
    
    Dennis用户应该可以访问处于同一对话中的其他用户。假设您要与另一个用户创建对话,您需要能够为他们创建订阅。