Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/34.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# 通过ID列表搜索数据库中的记录_C#_Asp.net_Asp.net Mvc_Performance_Linq - Fatal编程技术网

C# 通过ID列表搜索数据库中的记录

C# 通过ID列表搜索数据库中的记录,c#,asp.net,asp.net-mvc,performance,linq,C#,Asp.net,Asp.net Mvc,Performance,Linq,我有一个ID itemID的列表,我将其传递给查询,如下所示: using (var ctx = new MyEntities()) { ctx.Configuration.LazyLoadingEnabled = false; ctx.Configuration.AutoDetectChangesEnabled = false; ctx.Configuration.Vali

我有一个ID itemID的列表,我将其传递给查询,如下所示:

 using (var ctx = new MyEntities())
            {
                ctx.Configuration.LazyLoadingEnabled = false;
                ctx.Configuration.AutoDetectChangesEnabled = false;
                ctx.Configuration.ValidateOnSaveEnabled = false;
                ctx.Configuration.ProxyCreationEnabled = false;
                var storeItems = ctx.Items.AsNoTracking().Where(y => y.StoreID == 223250).ToList();
                var idList = storeItems.Select(y => y.Id).ToList();
                var storeTransactions = ctx.ItemTransactions.AsNoTracking().Where(r => idList.Contains(r.Id.Value)).ToList();
                return Json("Ok");
            }
快速总结一下。。。StoreItems列表,例如本例中的1001项

通过传递1001 item id来获取item事务,我得到了返回的结果

265000张唱片

这两个表没有通过任何关系连接,但是Id列被索引以改进结果

然而,上一次查询的性能非常糟糕,需要一分钟以上的时间才能完全选择完所有记录,即使我对其进行了所有的调整以加快速度,但仍然没有任何帮助

有人知道在获取项目事务时,我是否还缺少一些东西来加快最后一个查询的速度吗


有人能帮我吗?

问题是您将可操作ID列表存储到内存中,然后使用它再次查询。这意味着EF将把它转换为一个简单的IN查询,并对所有ID进行硬编码。实际上,我甚至怀疑,由于265000条记录的数量太多,它实际上会首先从数据库中获取所有ItemTransactions,然后在内存中执行查询。这导致性能不佳。但一个简单的更改将使性能显著提高:

using (var ctx = new MyEntities())
{
    ctx.Configuration.LazyLoadingEnabled = false;
    ctx.Configuration.AutoDetectChangesEnabled = false;
    ctx.Configuration.ValidateOnSaveEnabled = false;
    ctx.Configuration.ProxyCreationEnabled = false;
    var storeItems = ctx.Items.AsNoTracking().Where(y => y.StoreID == 223250);
    var idList = storeItems.Select(y => y.Id); //removed ToList on this and previous line
    var storeTransactions = ctx.ItemTransactions.AsNoTracking()
                               .Where(r => idList.Contains(r.Id.Value)).ToList();
    return Json("Ok");
}
我所做的唯一更改是删除代码中的ToList调用。这意味着idList是EF可以理解的IQueryable,它不会首先执行它,而是在最后一条语句中将它用作子查询或联接,这将具有更好的性能


还考虑如果您实际上需要ItMeExchange实例作为一个整体,或者您可以使用带有选择的投影仅查询实际需要的属性。这将减少必须在应用程序和数据库之间传输的数据量。

问题是您将可操作ID列表存储到内存中,然后再次使用它进行查询。这意味着EF将把它转换为一个简单的IN查询,并对所有ID进行硬编码。实际上,我甚至怀疑,由于265000条记录的数量太多,它实际上会首先从数据库中获取所有ItemTransactions,然后在内存中执行查询。这导致性能不佳。但一个简单的更改将使性能显著提高:

using (var ctx = new MyEntities())
{
    ctx.Configuration.LazyLoadingEnabled = false;
    ctx.Configuration.AutoDetectChangesEnabled = false;
    ctx.Configuration.ValidateOnSaveEnabled = false;
    ctx.Configuration.ProxyCreationEnabled = false;
    var storeItems = ctx.Items.AsNoTracking().Where(y => y.StoreID == 223250);
    var idList = storeItems.Select(y => y.Id); //removed ToList on this and previous line
    var storeTransactions = ctx.ItemTransactions.AsNoTracking()
                               .Where(r => idList.Contains(r.Id.Value)).ToList();
    return Json("Ok");
}
我所做的唯一更改是删除代码中的ToList调用。这意味着idList是EF可以理解的IQueryable,它不会首先执行它,而是在最后一条语句中将它用作子查询或联接,这将具有更好的性能

还考虑如果您实际上需要ItMeExchange实例作为一个整体,或者您可以使用带有选择的投影仅查询实际需要的属性。这将减少应用程序和数据库之间必须传输的数据量。

无需禁用数据库上的LazyLoadingEnabled选项,并使用AsQueryable,以便ID不会出现在内存中。我建议在这种情况下使用join

试试这个:

using ( var ctx = new MyEntities() )
{
    ctx.Configuration.LazyLoadingEnabled = true;
    ctx.Configuration.AutoDetectChangesEnabled = false;
    ctx.Configuration.ValidateOnSaveEnabled = false;
    ctx.Configuration.ProxyCreationEnabled = false;

    var idList = ctx.Items.AsNoTracking().Where( y => y.StoreID == 223250 ).Select( y => y.Id ).AsQueryable();

    var storeTransactions = ctx.ItemTransactions.AsNoTracking().Where( r => idList.Contains( r.Id.Value ) ).ToList();

    return Json( "Ok" );
}
不需要在数据库上禁用LazyLoadingEnabled选项,也不需要使用AsQueryable,这样ID就不会出现在内存中。我建议在这种情况下使用join

试试这个:

using ( var ctx = new MyEntities() )
{
    ctx.Configuration.LazyLoadingEnabled = true;
    ctx.Configuration.AutoDetectChangesEnabled = false;
    ctx.Configuration.ValidateOnSaveEnabled = false;
    ctx.Configuration.ProxyCreationEnabled = false;

    var idList = ctx.Items.AsNoTracking().Where( y => y.StoreID == 223250 ).Select( y => y.Id ).AsQueryable();

    var storeTransactions = ctx.ItemTransactions.AsNoTracking().Where( r => idList.Contains( r.Id.Value ) ).ToList();

    return Json( "Ok" );
}
你写道:

这两个表之间没有任何关系

很明显,这是有关系的。您希望ItemTranaction.Id.Value有时具有Item.Id的值

您将获得StoreId等于223250的所有项目。从这些项目中获取Id。给我所有的ItemTransactions都有一个Id。值,该值也在获取的Id中

换言之:

要求:给我所有ItemTransactions,其itemTransaction.Id.value的值等于StoreId等于223250的所有项目的Id之一

如果只在一个查询中执行查询,则查询速度会快得多:

int storeId = 223250;

var result = dbContext.ItemTransactions
  .Join(dbContext.Items.Where(item => item.StoreId == storeId),
  itemTransaction => itemTransaction.Id.Value,
  item => item.Id,
  (itemtransaction, item) => itemTransaction)
简言之:

将itemtransaction与StoreId等于storId的项目联接。 从每个itemTransaction中获取itemTransaction.Id.Value, 从每个项目中获取Id 当这些值相等时,获取itemTransaction和item以创建结果 这个结果就是itemTransaction 您没有这么说,但我认为item.Id是主键。这确保了没有两个项目具有相同的Id,因此所有剩余的itemTransactions都是唯一的。不需要使用Distinct。

您写道:

这两个表之间没有任何关系

很明显,这是有关系的。您希望ItemTranaction.Id.Value有时具有Item.Id的值

您将获得StoreId等于223250的所有项目。从这些项目中获取Id。给我所有的ItemTransactions都有一个Id。值,该值也在获取的Id中

换言之:

要求:给我所有ItemTransactions,其itemTransaction.Id.value的值等于StoreId等于223250的所有项目的Id之一

如果只在一个查询中执行查询,则查询速度会快得多:

int storeId = 223250;

var result = dbContext.ItemTransactions
  .Join(dbContext.Items.Where(item => item.StoreId == storeId),
  itemTransaction => itemTransaction.Id.Value,
  item => item.Id,
  (itemtransaction, item) => itemTransaction)
我 n字:

将itemtransaction与StoreId等于storId的项目联接。 从每个itemTransaction中获取itemTransaction.Id.Value, 从每个项目中获取Id 当这些值相等时,获取itemTransaction和item以创建结果 这个结果就是itemTransaction
您没有这么说,但我认为item.Id是主键。这确保了没有两个项目具有相同的Id,因此所有剩余的itemTransactions都是唯一的。不需要Distinct。

1001个ID是否真的存在265000条记录?或者记录中有任何重复?@er mfahhgk确实是265000:/it希望查看表之间的关系。还有一件事,为什么要使用ToList来提取所有列。1001个ID是否真的存在265000条记录?或者记录中有任何重复?@er mfahhgk确实是265000:/it希望查看表之间的关系。还有一件事,为什么要使用ToList来拉所有列。我认为AsQueryable实际上是不必要的。这个查询是IQueryable的,除非你调用ToList。我认为AsQueryable实际上是不必要的。该查询是可查询的,除非您致电ToList。嘿,谢谢您的快速回复!:我明白你打算删除托利斯特。。。这样就减少了数据库的负载,而无需执行项的查询本身。。。但对于交易而言,仍然需要大约65秒的时间…:/这真的很奇怪。。。最终返回了多少条记录?@Marin Zikmund 265757如果只在查询中使用普通计数而不是ToList,需要多长时间?在这种情况下需要421毫秒^^^嘿,谢谢你的快速回复!:我明白你打算删除托利斯特。。。这样就减少了数据库的负载,而无需执行项的查询本身。。。但对于交易而言,仍然需要大约65秒的时间…:/这真的很奇怪。。。最终返回了多少条记录?@Marin Zikmund 265757如果只在查询中使用普通计数而不是ToList,需要多长时间?本例中为421毫秒^^