C# 如何使用LINQ简化(加速)从包含100多万条记录的数据库中选择查询

C# 如何使用LINQ简化(加速)从包含100多万条记录的数据库中选择查询,c#,asp.net,sql-server,entity-framework,linq,C#,Asp.net,Sql Server,Entity Framework,Linq,我的应用程序中有两个模型:客户名称取自的客户和购买信息取自的付款。在结果中,我得到了每个客户在时间间隔内的购买清单-fromDate和toDate。但所有这些过程都需要太多的时间。因为客户的db大约有1500条记录,付款=0.5百万。那么我怎样才能加快这个过程呢 public async Task<List<SomeModel>> SomeMethod(DateTime? fromDate, DateTime? toDate) { var clients = aw

我的应用程序中有两个模型:客户名称取自的客户和购买信息取自的付款。在结果中,我得到了每个客户在时间间隔内的购买清单-
fromDate
toDate
。但所有这些过程都需要太多的时间。因为客户的db大约有1500条记录,付款=0.5百万。那么我怎样才能加快这个过程呢

public async Task<List<SomeModel>> SomeMethod(DateTime? fromDate, DateTime? toDate)
{
    var clients = await _db.Clients.ToListAsync();

    var totals = new List<SomeModel>();

    foreach (var client in clients)
    {
        var payment = await _db.Payments.Where(pay => pay.ClientId == client.Id).Where(
            p =>
                DateTime.Compare(p.TradeDate, (DateTime)fromDate) >= 0 &&
                DateTime.Compare(p.TradeDate, (DateTime)toDate) <= 0).ToListAsync();
        var totalsByCust = new SomeModel{ Username = client.Username };
        foreach (var item in payment)
        {
            totalByCust.Bcf += item.Bcf;
            totalByCust.Ecn += item.Ecn;
            totalByCust.Ecbt += item.Ecbt;
            totalByCust.OpenGl += item.OpenGl;
            totalByCust.JeyK += item.JeyK;

        }
        totals.Add(totalByCust);
    }
    return totals;
}
public async Task SomeMethod(DateTime?fromDate,DateTime?toDate)
{
var clients=await_db.clients.ToListAsync();
var totals=新列表();
foreach(客户机中的var客户机)
{
var payment=wait _db.Payments.Where(pay=>pay.ClientId==client.Id)。Where(
p=>
DateTime.Compare(p.TradeDate,(DateTime)fromDate)>=0&&

比较(p.TradeDate,(DateTime)toDate)使用SQLCommand将此代码移动到传统SQL语句中。Linq查询是逐行运行的,使用批处理查询时效率更高。

使用SQLCommand将此代码移动到传统SQL语句中。Linq查询是逐行运行的,使用批处理查询时效率更高。

您在向客户端付款时有导航属性。或者,您可以将所有客户端加载到字典中,因为只有1500个客户端。使用导航属性可以这样做:

public async Task<List<SomeModel>> SomeMethod(DateTime? fromDate, DateTime? toDate)
{
  return _db.Payments
    .Where(p =>
        DateTime.Compare(p.TradeDate, (DateTime)fromDate) >= 0 &&
        DateTime.Compare(p.TradeDate, (DateTime)toDate) <= 0))
    .GroupBy(p=>p.ClientId)
    .Select(g=>new SomeModel { 
      UserName = g.First().Client.UserName,
      Bcf = g.Sum(p=>p.Bcf),
      Ecn = g.Sum(p=>p.Ecn),
      Ecbt = g.Sum(p=>p.Ecbt),
      OpenGl = g.Sum(p=>p.OpenGl),
      JeyK = g.Sum(p=>p.JeyK)
    })
    .ToListAsync();
}
public async Task SomeMethod(DateTime?fromDate,DateTime?toDate)
{
返回_db.Payments
.其中(p=>
DateTime.Compare(p.TradeDate,(DateTime)fromDate)>=0&&
DateTime.Compare(p.TradeDate,(DateTime)toDate)p.ClientId)
.Select(g=>newsomemodel{
UserName=g.First().Client.UserName,
Bcf=g.Sum(p=>p.Bcf),
Ecn=g.Sum(p=>p.Ecn),
Ecbt=g.Sum(p=>p.Ecbt),
OpenGl=g.Sum(p=>p.OpenGl),
JeyK=g.Sum(p=>p.JeyK)
})
.ToListAsync();
}

确保您在向客户端付款时拥有导航属性。或者,您可以将所有客户端加载到字典中,因为只有1500个客户端。使用导航属性可以这样做:

public async Task<List<SomeModel>> SomeMethod(DateTime? fromDate, DateTime? toDate)
{
  return _db.Payments
    .Where(p =>
        DateTime.Compare(p.TradeDate, (DateTime)fromDate) >= 0 &&
        DateTime.Compare(p.TradeDate, (DateTime)toDate) <= 0))
    .GroupBy(p=>p.ClientId)
    .Select(g=>new SomeModel { 
      UserName = g.First().Client.UserName,
      Bcf = g.Sum(p=>p.Bcf),
      Ecn = g.Sum(p=>p.Ecn),
      Ecbt = g.Sum(p=>p.Ecbt),
      OpenGl = g.Sum(p=>p.OpenGl),
      JeyK = g.Sum(p=>p.JeyK)
    })
    .ToListAsync();
}
public async Task SomeMethod(DateTime?fromDate,DateTime?toDate)
{
返回_db.Payments
.其中(p=>
DateTime.Compare(p.TradeDate,(DateTime)fromDate)>=0&&
DateTime.Compare(p.TradeDate,(DateTime)toDate)p.ClientId)
.Select(g=>newsomemodel{
UserName=g.First().Client.UserName,
Bcf=g.Sum(p=>p.Bcf),
Ecn=g.Sum(p=>p.Ecn),
Ecbt=g.Sum(p=>p.Ecbt),
OpenGl=g.Sum(p=>p.OpenGl),
JeyK=g.Sum(p=>p.JeyK)
})
.ToListAsync();
}

组合查询可能是最简单的尝试:

public async Task<List<SomeModel>> SomeMethod(DateTime? fromDate, DateTime? toDate) {
    var totals = new List<SomeModel>();

    var clientswithpayments = await _db.Clients.Select(client => new {
        client.Username,
        payments =  _db.Payments.Where(pay => pay.ClientId == client.Id).Where(p =>
            DateTime.Compare(p.TradeDate, (DateTime)fromDate) >= 0 &&
            DateTime.Compare(p.TradeDate, (DateTime)toDate) <= 0)
    }).ToListAsync();

    foreach (var client in clientswithpayments) {
        var totalsByCust = new SomeModel { Username = client.Username };
        foreach (var payment in client.payments) {
            totalByCust.Bcf += payment.Bcf;
            totalByCust.Ecn += payment.Ecn;
            totalByCust.Ecbt += payment.Ecbt;
            totalByCust.OpenGl += payment.OpenGl;
            totalByCust.JeyK += payment.JeyK;

        }
        totals.Add(totalByCust);
    }
    return totals;
}
public async Task SomeMethod(DateTime?fromDate,DateTime?toDate){
var totals=新列表();
var clientswithpayments=await _db.Clients.Select(client=>new{
client.Username,
payments=\u db.payments.Where(pay=>pay.ClientId==client.Id)。Where(p=>
DateTime.Compare(p.TradeDate,(DateTime)fromDate)>=0&&
比较(p.TradeDate,(DateTime)toDate)new{
client.Username,
payments=\u db.payments.Where(pay=>pay.ClientId==client.Id)。Where(p=>
DateTime.Compare(p.TradeDate,(DateTime)fromDate)>=0&&
比较(p.TradeDate,(DateTime)toDate)新模型{
Username=cwp.Username,
Bcf=cwp.payments.Sum(),
Ecn=cwp.payments.Ecn.Sum(),
Ecbt=cwp.payments.Ecbt.Sum(),
OpenGl=cwp.payments.OpenGl.Sum(),
JeyK=cwp.payments.JeyK.Sum()
}
返回等待总计。ToListSync();
}

组合查询可能是最简单的尝试:

public async Task<List<SomeModel>> SomeMethod(DateTime? fromDate, DateTime? toDate) {
    var totals = new List<SomeModel>();

    var clientswithpayments = await _db.Clients.Select(client => new {
        client.Username,
        payments =  _db.Payments.Where(pay => pay.ClientId == client.Id).Where(p =>
            DateTime.Compare(p.TradeDate, (DateTime)fromDate) >= 0 &&
            DateTime.Compare(p.TradeDate, (DateTime)toDate) <= 0)
    }).ToListAsync();

    foreach (var client in clientswithpayments) {
        var totalsByCust = new SomeModel { Username = client.Username };
        foreach (var payment in client.payments) {
            totalByCust.Bcf += payment.Bcf;
            totalByCust.Ecn += payment.Ecn;
            totalByCust.Ecbt += payment.Ecbt;
            totalByCust.OpenGl += payment.OpenGl;
            totalByCust.JeyK += payment.JeyK;

        }
        totals.Add(totalByCust);
    }
    return totals;
}
public async Task SomeMethod(DateTime?fromDate,DateTime?toDate){
var totals=新列表();
var clientswithpayments=await _db.Clients.Select(client=>new{
client.Username,
payments=\u db.payments.Where(pay=>pay.ClientId==client.Id)。Where(p=>
DateTime.Compare(p.TradeDate,(DateTime)fromDate)>=0&&
比较(p.TradeDate,(DateTime)toDate)new{
client.Username,
payments=\u db.payments.Where(pay=>pay.ClientId==client.Id)。Where(p=>
DateTime.Compare(p.TradeDate,(DateTime)fromDate)>=0&&
比较(p.TradeDate,(DateTime)toDate)新模型{
Username=cwp.Username,
Bcf=cwp.payments.Sum(),
Ecn=cwp.payments.Ecn.Sum(),
Ecbt=cwp.payments.Ecbt.Sum(),
OpenGl=cwp.payments.OpenGl.Sum(),
JeyK=cwp.payments.JeyK.Sum()
}
返回等待总计。ToListSync();
}


您应该使用存储过程而不是Linq查询。

您应该使用存储过程而不是Linq查询。

@rene会发生什么?此过程将在服务器上花费相同的时间。。。(不,不会,试试看。SQL
JOIN
比连续向DB服务器发送1500个查询要高效得多。@rene my bad,edited。@不是。我相信最后一次编辑:p@rene会发生什么?这个过程在服务器上花费的时间相同。。。(不,不会,试试看。SQL
JOIN
将比连续向DB服务器发送1500个查询更有效。@rene my bad,edited。@不是。我相信最后一次编辑:pit更快,但需要更多内存。单次查询解决方案如何?我已经尝试过这种方法,然后我得到了systemOutOfMemory异常:)这种方法需要超过1GB的内存。不管怎样,谢谢你的关注。我真的很喜欢它!使用单查询解决方案?顺便说一句,我在单查询解决方案中有一个输入错误,我刚刚修复了一些创建和字段的模型。是的,它不允许更快,但是需要很多内存。单查询的速度如何