- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有一个来自 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/
我读了MSDN documentation但并没有真正理解它。 我相信Set的行为是“替换现有的,或添加”(原子地)。 正确吗? 最佳答案 如果该键已存在值, Add 不会执行任何操作(返回 fals
我试图找到一种方法让 .net 4.0 MemoryCache.Default 实例使用不区分大小写的比较器。 那可能吗? var bob = new object(); MemoryCache.De
我试图弄清楚应该如何使用 MemoryCache 以避免出现内存不足异常。我来自 ASP.Net 背景,缓存管理它自己的内存使用,所以我希望 MemoryCache 会做同样的事情。正如我制作的波纹管
在 Controller 类中,我有 using Microsoft.Extensions.Caching.Memory; private IMemoryCache _cache; private r
Memcached API 有一个 Touch() 方法,它可以更新给定 key 的过期策略。如何使用 .Net ObjectCache 类最好地完成此任务? 我能看到的最好的办法是删除对象并重新添加
当使用 MemoryCache 时,可以设置 AbsoluteExpiration AbsoluteExpirationRelativeToNow 例子: cache.GetOrCreate(
根据 MSDN 文档 here : Do not create MemoryCache instances unless it is required. If you create cache ins
我需要添加缓存功能并找到了一个名为 MemoryCache 的新类。但是,我发现 MemoryCache 有点残缺(我需要区域功能)。除其他事项外,我需要添加类似 ClearAll(region) 的
在我的应用程序中,我使用 MemoryCache,但我不希望项目过期。因此,项目将使用默认策略插入到缓存中,而无需设置 AbsoulteExpiration 或 SlidingExpiration。
MemoryCache类公开了一个名为 .AddOrGetExisting 的方法这是一种线程安全的方法,如果存在则获取,如果不存在则添加。 如果缓存对象不存在,此方法返回 NULL。我想我理解它的值
MemoryCache 是否具有缓存固定数量项目的功能? 例如我们只对从数据库中缓存 2000 个项目感兴趣。在不断向缓存中添加项目的同时,如果超过指定的项目数,则可以删除最旧的项目。 如果不是,我们
我正在使用 .NET 4.0 MemoryCache应用程序中的类并试图限制最大缓存大小,但在我的测试中,缓存似乎并没有真正遵守限制。 我正在使用设置,according to MSDN ,应该限制缓
我将 MemoryCache 与 Sql 依赖项一起使用。我注意到当使用 MemoryCache.Set() 时,如果集合中的某个项目被覆盖,则会发生内存泄漏。考虑以下场景: key=A 的项被插入到
我一直在阅读有关从 .Net Framework 4.0 开始的新 MemoryCache 类的所有地方。根据我的阅读,您可以跨不同的 .Net 应用程序访问 MemoryCache。我正在尝试在 A
我收到这条消息: System.ObjectDisposedException: Cannot access a disposed object. A common cause of this err
应用程序需要加载数据并缓存一段时间。我希望如果应用程序的多个部分想要同时访问同一个缓存键,缓存应该足够智能,只加载一次数据并将该调用的结果返回给所有调用者。然而, MemoryCache 不是这样做的
MemoryCache 是一个线程安全类,根据 this文章。但我不明白它在特定情况下会如何表现。例如我有代码: static private MemoryCache _cache = MemoryC
我不明白在 .NET 4.0 的 System.Runtime.Caching.MemoryCache 中滑动过期应该如何工作。 根据文档,过期时间跨度是“在从缓存中逐出缓存条目之前必须访问缓存条目的
在 .NET 4 MemoryCache 中,有没有办法找到上次访问项目的时间?我确定它在内部被跟踪,因为 CacheItemPolicy 具有 SlidingExpiration 属性。但是我找不到
我正在使用 .NET 4.0 MemoryCache类,我想以线程安全的方式添加或替换缓存中的现有项,但我还想知道我是否替换了现有项或添加了新项。 据我所知,Set方法旨在原子地替换缓存中的项目(如果
我是一名优秀的程序员,十分优秀!