gpt4 book ai didi

c# - 如何使用 MemoryCache 加速将各种对象转换为字符串?

转载 作者:太空宇宙 更新时间:2023-11-03 15:57:07 25 4
gpt4 key购买 nike

我有一个来自 Linq-To-Sql 查询的大型数据集(IEnumerable of [Table]-attributed class objects),我需要从中生成一个 CSV 文件它。我遍历数据集,对于每个项目,我使用各种格式选项将项目的每个属性的值转换为字符串。

Type t = typeof(T);
var properties = t.GetProperties();

foreach (var item in list)
{
foreach (var property in properties)
{
// This is made using delegates, but whatever
object value = property.GetValue(item, null);
// convert to string and feed to StringBuilder
}
}

问题是转换比运行查询花费的时间更长。数据集包含高度非规范化的数据——许多项目具有相同的属性和相同的值,只有一些属性具有不同的值。为数据集中的每个项目单独翻译每个属性值。所以我的代码一遍又一遍地将相同的数据转换为相同的字符串。我想以某种方式加快速度,最好不要更改 SQL 查询。

看起来像MemoryCache class可以工作,但我需要为每个对象制作唯一的键。我想不通如何可靠且高效地制作此类 key 。

如何使用 MemoryCache 来缓存不同类型对象的翻译结果?

最佳答案

如果您只是想加快速度,我建议您使用 ExpressionTrees 而不是 MemoryCache。这假设您没有要读取的嵌套对象,并且我可以在第一项上使用反射,并且它对于 IEnumerable 中的每个项目都是相同的——从问题中的示例代码来看,这似乎是正确的。

此外,如果它很大并且您打算将其写入文件,我建议直接使用 FileStream 而不是 StringBuilder。

public class CSV
{
public static StringBuilder ToCSV(IEnumerable list)
{
Func<object, object[]> toArray = null;
var sb = new StringBuilder();

// Need to initialize the loop and on the first one grab the properties to setup the columns
foreach (var item in list)
{
if (toArray == null)
{
toArray = ItemToArray(item.GetType());
}
sb.AppendLine(String.Join(",", toArray(item)));
}

return sb;
}

private static Func<object, object[]> ItemToArray(Type type)
{
var props = type.GetProperties().Where(p => p.CanRead);
var arrayBody = new List<Expression>();

// Create a parameter to take the item enumeration
var sourceObject = Expression.Parameter(typeof (object), "source");
// Convert it to the type that is passed in
var sourceParam = Expression.Convert(sourceObject, type);

foreach (var prop in props)
{
var propType = prop.PropertyType;

if (IsValueProperty(propType))
{
// get the value of the property
Expression currentProp = Expression.Property(sourceParam, prop);
// Need to box to an object if value type
if (propType.IsValueType)
{
currentProp = Expression.TypeAs(currentProp, typeof (object));
}
// Add to the collection of expressions so we can build the array off of this collection
arrayBody.Add(currentProp);
}
}
// Create an array based on the properties
var arrayExp = Expression.NewArrayInit(typeof (object), arrayBody);

// set a default return value of null if couldn't match
var defaultValue = Expression.NewArrayInit(typeof (object), Expression.Constant(null));

//Set up so the lambda can have a return value
var returnTarget = Expression.Label(typeof (object[]));
var returnExpress = Expression.Return(returnTarget, arrayExp, typeof (object[]));
var returnLabel = Expression.Label(returnTarget, defaultValue);

//Create the method
var code = Expression.Block(arrayExp, returnExpress, returnLabel);
return Expression.Lambda<Func<object, object[]>>(code, sourceObject).Compile();
}


private static bool IsValueProperty(Type propertyType)
{
var propType = propertyType;

if (propType.IsGenericType && propType.GetGenericTypeDefinition() == typeof (Nullable<>))
{
propType = new NullableConverter(propType).UnderlyingType;
}

return propType.IsValueType || propType == typeof (string);
}
}

关于c# - 如何使用 MemoryCache 加速将各种对象转换为字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23155115/

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