C# 如何使用MemoryCache加速将各种对象转换为字符串?
我有一个从Linq到Sql查询的大型数据集(C# 如何使用MemoryCache加速将各种对象转换为字符串?,c#,.net,caching,memorycache,C#,.net,Caching,Memorycache,我有一个从Linq到Sql查询的大型数据集(IEnumerable的[表]-属性化类对象),我需要从中生成一个CSV文件。我在数据集上循环,对于每个项目,我使用各种格式选项将项目的每个属性的值转换为字符串 Type t = typeof(T); var properties = t.GetProperties(); foreach (var item in list) { foreach (var property in properties) { // Thi
IEnumerable
的[表]
-属性化类对象),我需要从中生成一个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
,以便缓存不同类型对象的转换结果?如果您只是想加快转换速度,我建议使用ExpressionTrees而不是MemoryCache。这假设您没有要读取的嵌套对象,并且我可以对第一个项使用反射,并且IEnumerable中的每个项都是相同的-从问题中的示例代码来看,这似乎是正确的
另外,如果它很大,并且您要将其写入一个文件,我建议直接使用文件流,而不是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);
}
}
公共类CSV
{
公共静态StringBuilder ToCSV(IEnumerable列表)
{
Func toArray=null;
var sb=新的StringBuilder();
//需要初始化循环,在第一个循环中获取属性以设置列
foreach(列表中的变量项)
{
如果(toArray==null)
{
toArray=ItemToArray(item.GetType());
}
sb.AppendLine(String.Join(“,”,toArray(item));
}
归还某人;
}
专用静态Func ItemToArray(类型)
{
var props=type.GetProperties(),其中(p=>p.CanRead);
var arrayBody=新列表();
//创建一个参数以获取项枚举
var sourceObject=Expression.Parameter(typeof(object),“source”);
//将其转换为传入的类型
var sourceParam=Expression.Convert(sourceObject,type);
foreach(道具中的var道具)
{
var propType=prop.PropertyType;
if(IsValueProperty(propType))
{
//获取属性的值
表达式currentProp=Expression.Property(sourceParam,prop);
//如果值类型为,则需要框到对象
if(propType.IsValueType)
{
currentProp=Expression.TypeAs(currentProp,typeof(object));
}
//添加到表达式集合中,以便我们可以基于此集合构建数组
arrayBody.Add(currentProp);
}
}
//基于属性创建一个数组
var arrayExp=Expression.NewArrayInit(typeof(object),arrayBody);
//如果无法匹配,请将默认返回值设置为null
var defaultValue=Expression.NewArrayInit(typeof(object),Expression.Constant(null));
//设置以便lambda可以有一个返回值
var returnTarget=Expression.Label(typeof(object[]);
var returnExpress=Expression.Return(returnTarget,arrayExp,typeof(object[]);
var returnLabel=Expression.Label(returnTarget,defaultValue);
//创建方法
var代码=Expression.Block(arrayExp、returnExpress、returnLabel);
返回表达式.Lambda(代码,sourceObject).Compile();
}
私有静态bool IsValueProperty(类型propertyType)
{
var-propType=propertyType;
if(propType.IsGenericType&&propType.GetGenericTypeDefinition()==typeof(可为空))
{
propType=新的NullableConverter(propType).UnderlinedType;
}
返回propType.IsValueType | | propType==typeof(字符串);
}
}