Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用MemoryCache加速将各种对象转换为字符串?_C#_.net_Caching_Memorycache - Fatal编程技术网

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

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

我有一个从Linq到Sql查询的大型数据集(
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(字符串);
}
}