我在c#winforms上工作。我使用实体框架6。
在我的解决方案中,我有两个项目与A.BLL& A.DAL名称。 (A.DAL在A.BLL参考文献中添加)
A.DAL项目我有方法:
public decimal Sum(Func<ml_doc, bool> predicate, Func<ml_doc, decimal> sumColumn)
{
try
{
using (dbEnteties = new Entities(Connection.CustomEntityConnection))
{
dbEnteties.ContextOptions.LazyLoadingEnabled = true;
var dbe = dbEnteties.ml_doc;
return dbe.Where(predicate).Sum(sumColumn);
}
}
catch (Exception exp)
{
throw exp;
}
}
A.BLL项目我有方法(在A.DAL项目中使用Sum方法):
public decimal GetSum(long AccId, int? CntId, short BranchId, int BeginNumber)
{
try
{
using (dal = new DAL.DocDA())
{
// Sum method referenced from A.DAL project
return dal.Sum(
x =>
x.acc_id == AccId &&
x.cnt_id.Equals(CntId) &&
x.ml_doc_hdr.branch_id == BranchId &&
x.ml_doc_hdr.number >= BeginNumber
,
y => y.price);
}
}
catch (Exception exp)
{
throw exp;
}
}
当我使用GetSum方法(在A.BLL项目中)时,我得到了异常:
已经有一个与此命令关联的开放DataReader 必须先关闭。
要解决此异常,我将 MultipleActiveResultSets = True 添加到我的连接字符串中,此方法的工作速度非常慢(例如3秒)。
我在A.DAL项目的方法下创建:
public decimal Sum2(long AccId, int? CntId, short BranchId, int BeginNumber)
{
try
{
using (dbEnteties = new Entities(Connection.CustomEntityConnection))
{
dbEnteties.ContextOptions.LazyLoadingEnabled = true;
var resultQuery = dbEnteties.ml_doc.Where(
x =>
x.acc_id == AccId &&
x.cnt_id.Equals(CntId) &&
x.ml_doc_hdr.branch_id == BranchId &&
x.ml_doc_hdr.number >= BeginNumber
);
if (resultQuery.Count() != 0)
{
return resultQuery.Sum(x => x.price);
}
return 0;
}
}
catch (Exception exp)
{
throw exp;
}
}
当我使用上方法(Sum2)时,这种工作很好而且非常快(例如0.003秒)
Sum2(在A.DAL项目上)和&amp;之间的差异是什么? GetSum(关于A.BLL projetc)方法(似乎有相同的)?
如何更改GetSum方法以实现高性能?
答案 0 :(得分:5)
这一个:
public decimal Sum(Func<ml_doc, bool> predicate, Func<ml_doc, decimal> sumColumn)
{
try
{
using (dbEnteties = new Entities(Connection.CustomEntityConnection))
{
dbEnteties.ContextOptions.LazyLoadingEnabled = true;
var dbe = dbEnteties.ml_doc;
return dbe.Where(predicate).Sum(sumColumn);
}
}
catch (Exception exp)
{
throw exp;
}
}
从SQL服务器本地加载完整的ml_doc
表,然后在本地执行Where()
和Sum()
操作。
这是因为您的LINQ表达式使用了两个Func<>
个委托,因此不使用
Queryable.Where(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate)
Queryable.Sum(this IQueryable<TSource> source, Expression<Func<TSource, decimal>> selector)
它使用
Enumerable.Where(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
Enumerable.Sum(this IEnumerable<TSource> source, Func<TSource, decimal> selector)
尝试将其更改为:
public decimal Sum(Expression<Func<ml_doc, bool>> predicate, Expression<Func<ml_doc, decimal>> sumColumn)
Sum2
方法通过直接使用一些lambda函数,使用Queryable.*
方法,因为lambda函数被解释为Expression<>
。