Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.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# 有没有办法改进这个EF查询_C#_Sql Server_Entity Framework - Fatal编程技术网

C# 有没有办法改进这个EF查询

C# 有没有办法改进这个EF查询,c#,sql-server,entity-framework,C#,Sql Server,Entity Framework,在第三方使用的WebApi中,今天当他们调用方法时,我们开始遇到失败 该方法连接到两个表并联接它们。来自EF的错误消息为 查询处理器耗尽了内部资源,无法生成查询计划。这是一个罕见的事件,仅适用于非常复杂的查询或引用大量表或分区的查询。请简化查询。如果您认为此消息有误,请联系客户支持服务以获取更多信息 keys是检索到的lead ID的IEnumerable。基本上,我们提取ID列表,然后执行上述操作,检查密钥集合,以便查询返回准确的数据 密钥可容纳约28k个ID 请注意,这在迁移到Azure云后

在第三方使用的WebApi中,今天当他们调用方法时,我们开始遇到失败

该方法连接到两个表并联接它们。来自EF的错误消息为

查询处理器耗尽了内部资源,无法生成查询计划。这是一个罕见的事件,仅适用于非常复杂的查询或引用大量表或分区的查询。请简化查询。如果您认为此消息有误,请联系客户支持服务以获取更多信息

keys是检索到的lead ID的IEnumerable。基本上,我们提取ID列表,然后执行上述操作,检查密钥集合,以便查询返回准确的数据

密钥可容纳约28k个ID

请注意,这在迁移到Azure云后才开始成为一个问题,但我认为这是一个巧合

keys是检索到的lead ID的IEnumerable

密钥可容纳约28k个ID

因此:

return context.leads
            .Where(q => q.eventID == 1234)
            .Join(context.config,
                leads => leads.configId,
                config => config.configId,
                (leads, config) => new { leads, config })
            .Where(p => keys.Contains(p.leads.leadId))
将ID粘贴到SQL查询文本中,如:

SELECT … WHERE LeadId in (1,23,3,4,5,6,45,34, . . . )
这将导致大型、不可重用且解析和编译查询的成本高昂。最好将ID加载到表中并连接它们,或者使用XML、JSON或表值参数将它们传递给服务器

基本上,我们提取ID列表,然后执行上述操作

那就别那么做。如果您想要的ID列表在数据库中,那么将其加入到您的查询中。避免从数据库中读取28K ID,然后将其发送回查询体

keys是检索到的lead ID的IEnumerable

密钥可容纳约28k个ID

因此:

return context.leads
            .Where(q => q.eventID == 1234)
            .Join(context.config,
                leads => leads.configId,
                config => config.configId,
                (leads, config) => new { leads, config })
            .Where(p => keys.Contains(p.leads.leadId))
将ID粘贴到SQL查询文本中,如:

SELECT … WHERE LeadId in (1,23,3,4,5,6,45,34, . . . )
这将导致大型、不可重用且解析和编译查询的成本高昂。最好将ID加载到表中并连接它们,或者使用XML、JSON或表值参数将它们传递给服务器

基本上,我们提取ID列表,然后执行上述操作


那就别那么做。如果您想要的ID列表在数据库中,那么将其加入到您的查询中。避免从数据库中读取28K ID,然后将其发送回查询正文中。

要帮助澄清David的回答:

您用于获取28k ID的查询是什么?这就是您应该合并到此查询中的查询。获取ID对于相对较小的ID(而不是28k)来说效果很好。如果在EF中正确设置关系,则可以避免显式联接。EF不仅仅是SQL的替代包装器。虽然您可以使用断开连接的实体之间的显式连接来编写它,但当将其设置为相关实体相互了解的ORM时,它的功能要强大得多。您的EF表达式应该更像:

var leadsQuery = context.leads
    .Include(l => l.Config)  
    .Where(l => l.eventID == 1234
      && /* Insert criteria to determine which Leads to return. /*);
要插入的where子句不是来自ID的IEnumerable。这对于少量行很好。这应该是您用来获取这些ID的标准

潜在客户应具有对配置的引用。不需要为每个表声明dbset,然后告诉EF加入它们。如果潜在客户表具有ConfigId,则:

public class Lead
{
   //...
   public virtual Config Config { get; set; }
}
然后,如果这是EF core,则设置映射:(IEntityTypeConfiguration或OnModelCreating)

builder.Entity()
.HasOne(x=>x.Config)
.WithMany()//Lead有配置,而config没有Lead的集合。
.HasForeignKey(“ConfigId”);//为FK创建阴影特性。
或EF6

builder.Entity<Lead>()
  .HasRequired(x => x.Config)
  .WithMany()
  .Map(x => x.MapKey("ConfigId")); // Similar to above. Set up the relationship without a FK in the entity, map directly to the table.
builder.Entity()
.HasRequired(x=>x.Config)
.有很多
.Map(x=>x.MapKey(“ConfigId”);//与上面类似。设置实体中没有FK的关系,直接映射到表。

通过使用
.Include(l=>l.Config)
可以访问lead.Config属性以获取该lead的配置。不需要编写查询来分别返回Lead和Config以及其他数据。您不需要
.Include()
相关实体来查询它们,但是如果您想在通过属性进行查询后访问这些实体,则应使用
.Include()
以避免对数据库进行额外的延迟加载调用。(EF的一个强大功能,但如果不小心使用的话,这是一个昂贵的功能。)

为了帮助澄清David的回答:

您用于获取28k ID的查询是什么?这就是您应该合并到此查询中的查询。获取ID对于相对较小的ID(而不是28k)来说效果很好。如果在EF中正确设置关系,则可以避免显式联接。EF不仅仅是SQL的替代包装器。虽然您可以使用断开连接的实体之间的显式连接来编写它,但当将其设置为相关实体相互了解的ORM时,它的功能要强大得多。您的EF表达式应该更像:

var leadsQuery = context.leads
    .Include(l => l.Config)  
    .Where(l => l.eventID == 1234
      && /* Insert criteria to determine which Leads to return. /*);
要插入的where子句不是来自ID的IEnumerable。这对于少量行很好。这应该是您用来获取这些ID的标准

潜在客户应具有对配置的引用。不需要为每个表声明dbset,然后告诉EF加入它们。如果潜在客户表具有ConfigId,则:

public class Lead
{
   //...
   public virtual Config Config { get; set; }
}
然后,如果这是EF core,则设置映射:(IEntityTypeConfiguration或OnModelCreating)

builder.Entity()
.HasOne(x=>x.Config)
.WithMany()//Lead有配置,而config没有Lead的集合。
.HasForeignKey(“ConfigId”);//为FK创建阴影特性。
或EF6

builder.Entity<Lead>()
  .HasRequired(x => x.Config)
  .WithMany()
  .Map(x => x.MapKey("ConfigId")); // Similar to above. Set up the relationship without a FK in the entity, map directly to the table.
builder.Entity()
.HasRequired(x=>x.Config)
.有很多
.Map(x=>x.MapKey(“ConfigId”);//与上面类似。设置实体中没有FK的关系,直接映射到表。
通过使用
.Include(l=>l.Config)
可以访问lead.Config属性以获取该lead的配置。不需要编写查询来分别返回Lead和Config以及其他数据。查询相关实体时不需要
.Include()
相关实体,但是如果要在查询后通过属性访问这些实体,