gpt4 book ai didi

c# - 在内存中没有负载基础的情况下使用 LinqToSql

转载 作者:行者123 更新时间:2023-11-30 13:38:37 25 4
gpt4 key购买 nike

我有一个问题。如果我使用的是 LinqToSql,我的程序会将我的数据库加载到内存中。小例子:

//pageNumber = 1; pageSize = 100;                
var result =
(
from a in db.Stats.AsEnumerable()
where (DictionaryFilter(a, sourceDictionary) && DateFilter(a, beginTime, endTime) && ErrorFilter(a, WarnLevel))
select a
);
var size = result.Count(); // size = 1007
var resultList = result.Skip((pageNumber-1)*pageSize).Take(pageSize).ToList();
return resultList;

DictionaryFilter、DateFilter 和 ErrorFilter 是过滤我的数据库的函数。在此之后我的程序使用 ~250Mb 的 Ram。如果我不使用:

var size = result.Count(); 

我的程序使用 ~120MB Ram。在使用此代码之前,我的程序使用 ~35MB Ram。

如何使用 count 和 take 函数而不将所有数据库加载到内存中?

static bool DateFilter(Stat table, DateTime begin, DateTime end)
{

if ((table.RecordTime >= begin.ToFileTime()) && (table.RecordTime <= end.ToFileTime()))
{
return true;
}
return false;
}
static bool ErrorFilter(Stat table, bool[] WarnLevel)
{
if (WarnLevel[table.WarnLevel]) return true;
else return false;
}
static bool DictionaryFilter(Stat table, Dictionary<GetSourcesNameResult, bool> sourceDictionary)
{
foreach (var word in sourceDictionary)
{
if (table.SourceName == word.Key.SourceName)
{
return word.Value;
}
}
//
return false;
}

最佳答案

简单:不要使用 .AsEnumerable() 。这意味着“切换到 LINQ-to-Objects”。在此之前,db.StatsIQueryable<T> ,这是一个可组合 API,并且会按照您的预期进行。

然而,这意味着您不能使用像 DictionaryFilter 这样的 C# 方法。和 DateFilter ,并且必须根据 Expression 来组合事物应用程序接口(interface)。如果您能说明他们的事情,我可能会提供进一步的建议。

通过您的编辑,可以调整过滤,例如:

static IQueryable<Stat> ErrorFilter(IQueryable<Stat> source, bool[] WarnLevel) {
// extract the enabled indices (match to values)
int[] levels = WarnLevel.Select((val, index) => new { val, index })
.Where(pair => pair.val)
.Select(pair => pair.index).ToArray();

switch(levels.Length)
{
case 0:
return source.Where(x => false);
case 1:
int level = levels[0];
return source.Where(x => x.WarnLevel == level);
case 2:
int level0 = levels[0], level1 = levels[1];
return source.Where(
x => x.WarnLevel == level0 || x.WarnLevel == level1);
default:
return source.Where(x => levels.Contains(x.WarnLevel));
}
}

日期过滤器更简单:

static IQueryable<Stat> DateFilter(IQueryable<Stat> source,
DateTime begin, DateTime end)
{
var from = begin.ToFileTime(), to = end.ToFileTime();
return source.Where(table => table.RecordTime >= from
&& table.RecordTime <= to);
}

和字典有点像关卡:

static IQueryable<Stat> DictionaryFilter(IQueryable<Stat> source,
Dictionary<GetSourcesNameResult, bool> sourceDictionary)
{
var words = (from word in sourceDictionary
where word.Value
select word.Key.SourceName).ToArray();

switch (words.Length)
{
case 0:
return source.Where(x => false);
case 1:
string word = words[0];
return source.Where(x => x.SourceName == word);
case 2:
string word0 = words[0], word1 = words[1];
return source.Where(
x => x.SourceName == word0 || x.SourceName == word1);
default:
return source.Where(x => words.Contains(x.SourceName));
}
}

和:

IQueryable<Stat> result = db.Stats;
result = ErrorFilter(result, WarnLevel);
result = DateFiter(result, beginTime, endTime);
result = DictionaryFilter(result, sourceDictionary);
// etc - note we're *composing* a filter here

var size = result.Count(); // size = 1007
var resultList = result.Skip((pageNumber-1)*pageSize).Take(pageSize).ToList();
return resultList;

重点是我们现在使用 IQueryable<T>Expression独家。

关于c# - 在内存中没有负载基础的情况下使用 LinqToSql,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15786850/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com