这是 entlib 支持团队建议的一个简单而漂亮的 hack(您可以在http://entlib.codeplex.com/discussions/281833查看完整线程):
randylevy 星期一晚上 11:39 不,RowMapper 没有任何缓存。我所知道的数据访问应用程序块的唯一缓存是存储过程参数缓存。
如果您使用的是默认映射器,那么您可以自己缓存结果并传递给 ExecuteSqlStringAccessor 方法,因为它支持 IRowMapper 和 IResultSetMapper 重载。
例如:
public class RowMapperCache
{
private Dictionary<Type, object> cache = new Dictionary<Type, object>();
private object locker = new object();
public IRowMapper<T> GetCachedMapper<T>() where T : new()
{
Type type = typeof(T);
lock (locker)
{
if (!Contains(type))
{
cache[type] = MapBuilder<T>.BuildAllProperties();
}
}
return cache[type] as IRowMapper<T>;
}
private bool Contains(T type)
{
return cache.ContainsKey(type);
}
}
// retrieve default mapper and cache it
IRowMapper<Region> regionMapper = rowMapperCache.GetCachedMapper<Region>();
var db = EnterpriseLibraryContainer.Current.GetInstance<Database>();
var r = db.ExecuteSqlStringAccessor<Region>("SELECT * FROM Region", regionMapper);
再次从 EntLib更新(更好的解决方案):
谢谢。也许,它可以放在 Enterprise Library 6 的桌面上,因为它看起来是个好主意?
只是为了好玩,我对示例进行了一些改进,将 RowMapperCache 作为单例存储在 EnterpriseLibraryContainer 中,以便可以像其他 Enterprise Library 对象一样检索它。尽管不是企业库“本机”类,但 RowMapperCache 仅与企业库一起使用,因此将其存储在容器中并不是一个巨大的飞跃(尤其是如果您没有使用完整的 Unity IoC)。
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ContainerModel;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ContainerModel.Unity;
using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.Practices.ServiceLocation;
using Microsoft.Practices.Unity;
namespace RowMapperConsole
{
public class Region {}
public class RowMapperCache
{
private Dictionary<Type, object> cache = new Dictionary<Type, object>();
private object locker = new object();
public IRowMapper<T> GetCachedMapper<T>() where T : new()
{
Type type = typeof(T);
lock (locker)
{
if (!Contains(type))
{
cache[type] = MapBuilder<T>.BuildAllProperties();
}
}
return cache[type] as IRowMapper<T>;
}
private bool Contains(T type)
{
return cache.ContainsKey(type);
}
}
class Program
{
static void Main(string[] args)
{
ApplicationInitialize();
// ...
IEnumerable<Region> regions = GetRegions();
}
public static void ApplicationInitialize()
{
ConfigureContainer(container =>
{
// Register as Singleton
container.RegisterType<RowMapperCache>(new ContainerControlledLifetimeManager());
});
}
public static void ConfigureContainer(Action<IUnityContainer> action)
{
IUnityContainer container = new UnityContainer();
if (action != null)
action(container);
IContainerConfigurator configurator = new UnityContainerConfigurator(container);
EnterpriseLibraryContainer.ConfigureContainer(configurator, ConfigurationSourceFactory.Create());
IServiceLocator locator = new UnityServiceLocator(container);
EnterpriseLibraryContainer.Current = locator;
}
public static IEnumerable<Region> GetRegions()
{
IRowMapper<Region> regionMapper = EnterpriseLibraryContainer.Current.GetInstance<RowMapperCache>()
.GetCachedMapper<Region>();
var db = EnterpriseLibraryContainer.Current.GetInstance<Database>();
return db.ExecuteSqlStringAccessor<Region>("SELECT * FROM Region", regionMapper).ToList();
}
}
}